/*
**  Copyright (c) 2014 Michael Liu(michael.liu.point@gmail.com).
**
**  Project: Gateway Unified Management Platform
**  File:      mtk7620_ifopt.c
**  Author:  Michael
**  Date:    03/20/2014
**
**  Purpose:
**    mtk7620 interface operation implement.
*/

/* Include files. */

#include "mtk7620_local.h"

/* Macro constant definitions. */

#if WIRELESS_EXT <= 11
#ifndef SIOCDEVPRIVATE
#define SIOCDEVPRIVATE 0x8BE0
#endif
#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
#endif

#define RT_PRIV_IOCTL						(SIOCIWFIRSTPRIV + 0x01)
#define RTPRIV_IOCTL_GSITESURVEY			(SIOCIWFIRSTPRIV + 0x0D)
#define RTPRIV_IOCTL_WSC_PROFILE			(SIOCIWFIRSTPRIV + 0x12)
#define RTPRIV_IOCTL_GET_MAC_TABLE_STRUCT	(SIOCIWFIRSTPRIV + 0x1F)

#define RT_OID_SYNC_RT61					0x0D010750
#define RT_OID_WSC_QUERY_STATUS				((RT_OID_SYNC_RT61 + 0x01) & 0xffff)

#define MAX_NUMBER_OF_MAC					(256)

#define MODE_CCK			0
#define MODE_OFDM			1
#define MODE_HTMIX			2
#define MODE_HTGREENFIELD	3
#define MODE_VHT			4

#define Rate_MCS			10

/* Type definitions. */

typedef struct _SITE_SURVEY {
	unsigned char channel;
	char ssid[35];
	char bssid[20];
	char security[23];
	unsigned char rssi;
	char apmode[9];
	char ext_ch[7];
	char net_type[3];
	char wps[4];
	char dpid[5];
} SITE_SURVEY;

enum Rate_BW {
	Rate_BW_20 = 0,
	Rate_BW_40,
	Rate_BW_80,
	Rate_BW_MAX
};

enum Rate_GI {
	Rate_800ns_GI = 0,
	Rate_400ns_GI,
	Rate_GI_MAX
};

typedef union {
	struct {
		unsigned short MCS:7;
		unsigned short BW:1;
		unsigned short ShortGI:1;
		unsigned short STBC:2;
		unsigned short eTxBF:1;
		unsigned short rsv:1;
		unsigned short iTxBF:1;
		unsigned short MODE:2;
	} field;
	unsigned short word;
} HTTRANSMIT_SETTING_24G, *PHTTRANSMIT_SETTING_24G;

typedef union {
	struct {
		unsigned short MCS:6;
		unsigned short ldpc:1;
		unsigned short BW:2;
		unsigned short ShortGI:1;
		unsigned short STBC:1;
		unsigned short eTxBF:1;
		unsigned short iTxBF:1;
		unsigned short MODE:3;
	} field;
	unsigned short word;
} HTTRANSMIT_SETTING_5G, *PHTTRANSMIT_SETTING_5G;

typedef struct _RT_802_11_MAC_ENTRY {
#if 1				//def CONFIG_RT2860V2_AP_V24_DATA_STRUCTURE
	unsigned char ApIdx;
#endif
	unsigned char Addr[6];
	unsigned char Aid;
	unsigned char Psm;	// 0:PWR_ACTIVE, 1:PWR_SAVE
	unsigned char MimoPs;	// 0:MMPS_STATIC, 1:MMPS_DYNAMIC, 3:MMPS_Enabled
	char AvgRssi0;
	char AvgRssi1;
	char AvgRssi2;
	unsigned int ConnectedTime;
	unsigned short TxRate;
	unsigned int LastRxRate;
#if 0
	int StreamSnr[3];
	int SoundingRespSnr[3];
#else
	short StreamSnr[3];
	short SoundingRespSnr[3];
#endif
#if 0
	short TxPER;
	short reserved;
#endif
} RT_802_11_MAC_ENTRY;

typedef struct _RT_802_11_MAC_TABLE {
	unsigned long Num;
	RT_802_11_MAC_ENTRY Entry[MAX_NUMBER_OF_MAC];
} RT_802_11_MAC_TABLE;

/* Local function declarations. */

static void mtk_wlan_get_bitrate(unsigned char MODE, unsigned char ShortGI, unsigned char BW,
				 unsigned char MCS, unsigned long *rate);

/* Macro API definitions. */

/* Global variable declarations. */

static char site_survey_buf[8192];
static SITE_SURVEY site_survey_array[64];

e_ret pf_dep_wlancli_set_linkenable(tdp_if * dp_if, e_bool enable, e_bool save)
{
	int rc = -1;
	char val[8];
	char iwpriv_arg[128];

	sysmgr_dbg("if[%s], set Link Enable -> [%c]\n", dp_if->name, enable ? 'Y' : 'N');

	sprintf(iwpriv_arg, "%s=%d", "ApCliEnable", ((enable == eBOOL_TRUE) ? 1 : 0));
	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0) {
		return (eRET_FAILURE);
	}

	if (save) {
		if (enable) {
#ifndef APCLI_BOND_SUPPORT
			dp_if_set_bridge_uplink(dp_if->name);
#else
			dp_if_bond_member_opt(dp_if->name, eBOOL_TRUE);
			add_apcli_bond_if_to_br(dp_if->data_paths);
#endif
		}

		sprintf(val, "%d", enable);
		if (dp_if->type == eDP_IF_TYPE_WLAN24G_CLI) {
			pf_dep_cfg_set_val(RT2860_NVRAM, "ApCliEnable", val);
		} else {
			pf_dep_cfg_set_val(RTDEV_NVRAM, "ApCliEnable", val);
		}
	}

	os_dep_if_up(dp_if->name);

	return (eRET_SUCCESS);
}

e_ret pf_dep_wlancli_set_ssid(tdp_if * dp_if, char *ssid)
{
	char iwpriv_arg[128];
	int cfg_idx;
	int rc = -1;

	sysmgr_dbg("if[%s], set SSID -> [%s]\n", dp_if->name, ssid);

	sprintf(iwpriv_arg, "%s=%s", WLAN_CLI_SSID_KEY, ssid);
	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0) {
		return (eRET_FAILURE);
	}

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_CLI) {
		cfg_idx = RT2860_NVRAM;
	} else {
		cfg_idx = RTDEV_NVRAM;
	}

	pf_dep_cfg_set_val(cfg_idx, WLAN_CLI_SSID_KEY, ssid);

	return (eRET_SUCCESS);

}

e_ret pf_dep_wlancli_set_bssid(tdp_if * dp_if, char *bssid)
{
	char iwpriv_arg[128];
	int cfg_idx;
	int rc = -1;

	sysmgr_dbg("if[%s], set BSSID -> [%s]\n", dp_if->name, bssid);

	sprintf(iwpriv_arg, "%s=%s", WLAN_CLI_BSSID_KEY, bssid);
	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0) {
		return (eRET_FAILURE);
	}

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_CLI) {
		cfg_idx = RT2860_NVRAM;
	} else {
		cfg_idx = RTDEV_NVRAM;
	}

	pf_dep_cfg_set_val(cfg_idx, WLAN_CLI_BSSID_KEY, bssid);

	return (eRET_SUCCESS);

}

e_ret pf_dep_wlancli_set_channel(tdp_if * dp_if, unsigned char channel, unsigned char ext_channel)
{
	char iwpriv_arg[128];
	char channel_val[8];
	int cfg_idx;
	int rc = -1;

	sysmgr_dbg("if[%s], set Channel -> [%d]\n", dp_if->name, channel);

	sprintf(iwpriv_arg, "%s=%d", WLAN_AP_CHANNEL_KEY, channel);
	sprintf(channel_val, "%d", channel);

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_CLI) {
		cfg_idx = RT2860_NVRAM;
		rc = do_iwpriv(WLAN_24G_AP_IF, "set", iwpriv_arg);
		if (rc < 0) {
			return (eRET_FAILURE);
		}

		if (ext_channel == eWLAN_EXT_CHANNEL_BELOW) {
			sprintf(iwpriv_arg, "%s=%s", WLAN_AP_HT_EXTCHA, "0");
			do_iwpriv(WLAN_24G_AP_IF, "set", iwpriv_arg);
			pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP1_HT_EXTCHA, "0");
		} else if (ext_channel == eWLAN_EXT_CHANNEL_ABOVE) {
			sprintf(iwpriv_arg, "%s=%s", WLAN_AP_HT_EXTCHA, "1");
			do_iwpriv(WLAN_24G_AP_IF, "set", iwpriv_arg);
			pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP1_HT_EXTCHA, "1");
		}
	} else {
		cfg_idx = RTDEV_NVRAM;
		rc = do_iwpriv(WLAN_5G_AP_IF, "set", iwpriv_arg);
		if (rc < 0) {
			return (eRET_FAILURE);
		}
	}

	pf_dep_cfg_set_val(cfg_idx, WLAN_AP_CHANNEL_KEY, channel_val);
	pf_dep_cfg_set_val(cfg_idx, WLAN_AP_AUTO_CH_SEL_KEY, "0");

	return (eRET_SUCCESS);

}

e_ret pf_dep_wlancli_set_sec_stuff(tdp_if * dp_if, unsigned char auth_mode,
				   unsigned char enc_method, twlan_sec_key * sec_key)
{
	char iwpriv_arg[128];
	char var_auth[32], var_enc[32], var_wpamix[32], var_defkeyid[4];
	int rc = -1;
	int cfg_idx;
	int key_len;

	sysmgr_dbg("if[%s], set: Auth mode -> [%u]; enc method -> [%u];\n", dp_if->name, auth_mode, enc_method);

	/* Sanity Check */
	switch (auth_mode) {
	case eWLAN_AUTH_MODE_OPEN:
		if ((enc_method != eWLAN_ENC_METHOD_NONE) && (enc_method != eWLAN_ENC_METHOD_WEP)) {
			sysmgr_err("Invalid EncrypType:%d for Auth:%d\n", enc_method, auth_mode);
			return (eRET_INVALID_ARG);
		}
		if (enc_method == eWLAN_ENC_METHOD_WEP) {
			sysmgr_dbg("key default id [%u]:\n"
				   "1: value: [%s]\n"
				   "2: value: [%s]\n"
				   "3: value: [%s]\n"
				   "4: value: [%s]\n",
				   sec_key->wep_key.default_id,
				   sec_key->wep_key.key[0].value,
				   sec_key->wep_key.key[1].value,
				   sec_key->wep_key.key[2].value, sec_key->wep_key.key[3].value);

			key_len = strlen(sec_key->wep_key.key[sec_key->wep_key.default_id - 1].value);
			if ((key_len != 5) && (key_len != 10) && (key_len != 13) && (key_len != 26)) {
				sysmgr_err("Invalid Key Length:%d\n", key_len);
				return (eRET_INVALID_ARG);
			}
		}
		break;

	case eWLAN_AUTH_MODE_SHARED:
	case eWLAN_AUTH_MODE_WEPAUTO:
		if (enc_method != eWLAN_ENC_METHOD_WEP) {
			sysmgr_err("Invalid EncrypType:%d for Auth:%d\n", enc_method, auth_mode);
			return (eRET_INVALID_ARG);
		}
		sysmgr_dbg("key default id [%u]:\n"
			   "1: value: [%s]\n"
			   "2: value: [%s]\n"
			   "3: value: [%s]\n"
			   "4: value: [%s]\n",
			   sec_key->wep_key.default_id,
			   sec_key->wep_key.key[0].value,
			   sec_key->wep_key.key[1].value, sec_key->wep_key.key[2].value, sec_key->wep_key.key[3].value);
		key_len = strlen(sec_key->wep_key.key[sec_key->wep_key.default_id - 1].value);
		if ((key_len != 5) && (key_len != 10) && (key_len != 13) && (key_len != 26)) {
			sysmgr_err("Invalid Key Length:%d\n", key_len);
			return (eRET_INVALID_ARG);
		}
		break;
	case eWLAN_AUTH_MODE_WPAPSK:
	case eWLAN_AUTH_MODE_WPA2PSK:
		sysmgr_dbg("key[%s];\n", sec_key->wpa_psk);
		if ((enc_method != eWLAN_ENC_METHOD_TKIP) && (enc_method != eWLAN_ENC_METHOD_AES)) {
			sysmgr_err("Invalid EncrypType:%d for Auth:%d\n", enc_method, auth_mode);
			return (eRET_INVALID_ARG);
		}
		key_len = strlen(sec_key->wpa_psk);
		if ((key_len < 8) || (key_len > 64)) {
			sysmgr_err("Invalid Key Length:%d\n", key_len);
			return (eRET_INVALID_ARG);
		}
		break;
	case eWLAN_AUTH_MODE_WPAPSKWPA2PSK:
		sysmgr_dbg("key[%s];\n", sec_key->wpa_psk);
		if (enc_method != eWLAN_ENC_METHOD_TKIP_AES) {
			sysmgr_err("Invalid EncrypType:%d for Auth:%d\n", enc_method, auth_mode);
			return (eRET_INVALID_ARG);
		}
		key_len = strlen(sec_key->wpa_psk);
		if ((key_len < 8) || (key_len > 64)) {
			sysmgr_err("Invalid Key Length:%d\n", key_len);
			return (eRET_INVALID_ARG);
		}
		break;

	case eWLAN_AUTH_MODE_WPA:
		break;
	case eWLAN_AUTH_MODE_WPA2:
		break;
	case eWLAN_AUTH_MODE_WPAWPA2:
		break;

	case eWLAN_AUTH_MODE_WPANONE:
	default:
		sysmgr_err("Invalid AuthMode:%d\n", auth_mode);
		return (eRET_INVALID_ARG);
	}

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_CLI) {
		cfg_idx = RT2860_NVRAM;
	} else {
		cfg_idx = RTDEV_NVRAM;
	}

	authmode_to_pd_dep_authmode(auth_mode, var_auth);
	enctype_to_pd_dep_enctype(enc_method, auth_mode, var_enc, var_wpamix);

	switch (enc_method) {
	case eWLAN_ENC_METHOD_NONE:
		break;

	case eWLAN_ENC_METHOD_WEP:
		sprintf(iwpriv_arg, "%s=%u", WLAN_CLI_ENC_WEP_DEFAULT_KEY_ID_KEY, sec_key->wep_key.default_id);
		sprintf(var_defkeyid, "%u", sec_key->wep_key.default_id);
		rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
		if (rc < 0) {
			return (eRET_FAILURE);
		}
		pf_dep_cfg_set_val(cfg_idx, WLAN_CLI_ENC_WEP_DEFAULT_KEY_ID_KEY, var_defkeyid);

		key_len = strlen(sec_key->wep_key.key[0].value);
		if ((key_len == 5) || (key_len == 10) || (key_len == 13) || (key_len == 26)) {

			sprintf(iwpriv_arg, "%s=%s", WLAN_CLI_ENC_WEP_KEY1_KEY, sec_key->wep_key.key[0].value);
			rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
			if (rc < 0) {
				return (eRET_FAILURE);
			}
			pf_dep_cfg_set_val(cfg_idx, WLAN_CLI_ENC_WEP_KEY1_STR_KEY, sec_key->wep_key.key[0].value);
			pf_dep_cfg_set_val(cfg_idx, WLAN_CLI_ENC_WEP_KEY1_TYPE_KEY,
					   (((key_len == 5) || (key_len == 10)) ? "1" : "0"));
		}

		key_len = strlen(sec_key->wep_key.key[1].value);
		if ((key_len == 5) || (key_len == 10) || (key_len == 13) || (key_len == 26)) {

			sprintf(iwpriv_arg, "%s=%s", WLAN_CLI_ENC_WEP_KEY2_KEY, sec_key->wep_key.key[1].value);
			rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
			if (rc < 0) {
				return (eRET_FAILURE);
			}
			pf_dep_cfg_set_val(cfg_idx, WLAN_CLI_ENC_WEP_KEY2_STR_KEY, sec_key->wep_key.key[1].value);

			pf_dep_cfg_set_val(cfg_idx, WLAN_CLI_ENC_WEP_KEY2_TYPE_KEY,
					   (((key_len == 5) || (key_len == 10)) ? "1" : "0"));
		}

		key_len = strlen(sec_key->wep_key.key[2].value);
		if ((key_len == 5) || (key_len == 10) || (key_len == 13) || (key_len == 26)) {

			sprintf(iwpriv_arg, "%s=%s", WLAN_CLI_ENC_WEP_KEY3_KEY, sec_key->wep_key.key[2].value);
			rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
			if (rc < 0) {
				return (eRET_FAILURE);
			}
			pf_dep_cfg_set_val(cfg_idx, WLAN_CLI_ENC_WEP_KEY1_STR_KEY, sec_key->wep_key.key[2].value);
			pf_dep_cfg_set_val(cfg_idx, WLAN_CLI_ENC_WEP_KEY3_TYPE_KEY,
					   (((key_len == 5) || (key_len == 10)) ? "1" : "0"));
		}

		key_len = strlen(sec_key->wep_key.key[3].value);
		if ((key_len == 5) || (key_len == 10) || (key_len == 13) || (key_len == 26)) {

			sprintf(iwpriv_arg, "%s=%s", WLAN_CLI_ENC_WEP_KEY4_KEY, sec_key->wep_key.key[3].value);
			rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
			if (rc < 0) {
				return (eRET_FAILURE);
			}
			pf_dep_cfg_set_val(cfg_idx, WLAN_CLI_ENC_WEP_KEY4_STR_KEY, sec_key->wep_key.key[3].value);
			pf_dep_cfg_set_val(cfg_idx, WLAN_CLI_ENC_WEP_KEY4_TYPE_KEY,
					   (((key_len == 5) || (key_len == 10)) ? "1" : "0"));
		}
		break;

	case eWLAN_ENC_METHOD_TKIP:
	case eWLAN_ENC_METHOD_AES:
	case eWLAN_ENC_METHOD_TKIP_AES:
		sprintf(iwpriv_arg, "%s=%s", WLAN_CLI_ENC_WPAPSK_KEY, sec_key->wpa_psk);
		rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
		if (rc < 0) {
			return (eRET_FAILURE);
		}
		pf_dep_cfg_set_val(cfg_idx, WLAN_CLI_ENC_WPAPSK_KEY, sec_key->wpa_psk);
		break;
	}

	if (var_auth[0] != 0) {
		sprintf(iwpriv_arg, "%s=%s", WLAN_CLI_AUTH_MODE_KEY, var_auth);
		rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
		if (rc < 0) {
			return (eRET_FAILURE);
		}
		pf_dep_cfg_set_val(cfg_idx, WLAN_CLI_AUTH_MODE_KEY, var_auth);
	}

	if (var_enc[0] != 0) {
		sprintf(iwpriv_arg, "%s=%s", WLAN_CLI_ENC_TYPE_KEY, var_enc);
		rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
		if (rc < 0) {
			return (eRET_FAILURE);
		}
		pf_dep_cfg_set_val(cfg_idx, WLAN_CLI_ENC_TYPE_KEY, var_enc);
	}

	return (eRET_SUCCESS);

}

e_ret pf_dep_wlancli_scan_aps(tdp_if * dp_if, twlan_cli_if_link_status ** aps)
{
	e_ret ret;
	e_bool got_line;
	int i;
	int rc = -1;
	int sockfd = -1;
	int ap_counter;
	char *line_start, *line_end, *buf_start, *buf_end;
	int item_size;
	char *item_start, *item_end;
	char encryptype[9], authtype[16];
	twlan_cli_if_link_status *result;
	struct iwreq wrq;

	sysmgr_dbg("if[%s] start scaning aps;\n", dp_if->name);
	rc = do_iwpriv(dp_if->name, "set", "SiteSurvey=1");
	if (rc < 0) {
		*aps = NULL;
		return (eRET_FAILURE);
	}

	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if (sockfd < 0) {
		sysmgr_err("socket() failed, err: %d,[%s]\n", errno, strerror(errno));
		*aps = NULL;
		return (eRET_FAILURE);
	}

	ap_counter = 0;
	result = NULL;
	memset(site_survey_buf, 0x0, sizeof(site_survey_buf));

	strcpy(wrq.ifr_name, dp_if->name);
	wrq.u.data.length = sizeof(site_survey_buf);
	wrq.u.data.pointer = site_survey_buf;
	wrq.u.data.flags = 0;
	rc = ioctl(sockfd, RTPRIV_IOCTL_GSITESURVEY, &wrq);
	sysmgr_dbg("\n=======Get Site Survey AP List[rc: %d]==========\n", rc);
	if (rc < 0) {
		sysmgr_err("ioctl() failed, err: %d,[%s]\n", errno, strerror(errno));
		ret = eRET_FAILURE;
		goto out;
	}

	if (wrq.u.data.length <= 0) {
		ret = eRET_FAILURE;
		goto out;
	}

	/* buffer get line init. */
	buf_start = wrq.u.data.pointer;
	buf_end = &buf_start[wrq.u.data.length - 1];
	buf_get_line_init(line_start, line_end, buf_start);

	/* Skip table head line. */
	buf_get_line(line_start, line_end, buf_start, buf_end);

	memset(site_survey_array, 0x0, sizeof(site_survey_array));

	do {
		got_line = buf_get_line(line_start, line_end, buf_start, buf_end);
		//sysmgr_dbg("got_line[%c], line_start[%p], line_end[%p], buf_start[%p], buf_end[%p]\n",
		//      ((got_line) ? 'Y' : 'N'), line_start, line_end, buf_start, buf_end);
		if (got_line) {
			int ssid_size = 0;
			int tmp_int_val;

			//sysmgr_dbg("line[%s]\n", line_start);

			item_end = line_start;

			/* Get channel. */
			item_start = item_end;
			item_end = item_start + 4;
			sscanf(item_start, "%d", &tmp_int_val);
			site_survey_array[ap_counter].channel = tmp_int_val;

			/* Get SSID. */
			ssid_size = 0;
			item_start = item_end;
			item_start = strchr(item_start, '\"');
			if (item_start != NULL) {
				/* skip ["] */
				item_start++;
				item_end = strchr(item_start, '\"');
				if (item_end != NULL) {
					ssid_size = item_end - item_start;
					/* skip ["  ] */
					item_end += 3;
				}
			}
			if (ssid_size != 0) {
				str_safe_cpy(site_survey_array[ap_counter].ssid, item_start, ssid_size);
			}

			/* Get BSSID, Security, RSSI, Mode, Ext-Channel, Network Type, Wps. */
			item_start = item_end;
			sscanf(item_start, "%s %s %d %s %s %s %s",
			       site_survey_array[ap_counter].bssid,
			       site_survey_array[ap_counter].security,
			       &tmp_int_val,
			       site_survey_array[ap_counter].apmode,
			       site_survey_array[ap_counter].ext_ch,
			       site_survey_array[ap_counter].net_type, site_survey_array[ap_counter].wps);

			site_survey_array[ap_counter].rssi = tmp_int_val;
			item_end = item_start + 20 + 23 + 9 + 7 + 7 + 3 + 4;

			/* Get DPID. */
			item_start = item_end;
			if (strstr(item_start, "PIN") != NULL) {
				strcpy(site_survey_array[ap_counter].dpid, "PIN");
			} else if (strstr(item_start, "PBC") != NULL) {
				strcpy(site_survey_array[ap_counter].dpid, "PBC");
			} else {
				site_survey_array[ap_counter].dpid[0] = 0;
			}

#if 0
			sysmgr_dbg("ssid:%s\n", site_survey_array[ap_counter].ssid);
			sysmgr_dbg("bssid:%s\n", site_survey_array[ap_counter].bssid);
			sysmgr_dbg("channel:%d\n", site_survey_array[ap_counter].channel);
			sysmgr_dbg("encrytype:%s\n", site_survey_array[ap_counter].security);
			sysmgr_dbg("rssi:%d\n", site_survey_array[ap_counter].rssi);
			sysmgr_dbg("apmode:%s\n", site_survey_array[ap_counter].apmode);
			sysmgr_dbg("ext_ch:%s\n", site_survey_array[ap_counter].ext_ch);
			sysmgr_dbg("NT:%s\n", site_survey_array[ap_counter].net_type);
			sysmgr_dbg("wps:%s\n", site_survey_array[ap_counter].wps);
			sysmgr_dbg("dpid:%s\n\n", site_survey_array[ap_counter].dpid);
#endif

			ap_counter++;
		} else {
			//sysmgr_dbg("buf_get_line() finish.\n");
			break;
		}
	} while (1);

	if (ap_counter == 0) {
		ret = eRET_SUCCESS;
		goto out;
	}

	result = malloc(sizeof(twlan_cli_if_link_status) + ap_counter * sizeof(twlan_cli_if_link_entry));
	if (result == NULL) {
		ret = eRET_NO_RESOURCE;
		goto out;
	}

	memset(result, 0x0, sizeof(twlan_cli_if_link_status) + ap_counter * sizeof(twlan_cli_if_link_entry));

	result->counter = ap_counter;

	for (i = 0; i < ap_counter; i++) {
		strcpy(result->aps[i].ssid, site_survey_array[i].ssid);
		strcpy(result->aps[i].bssid, site_survey_array[i].bssid);
		result->aps[i].channel = site_survey_array[i].channel;
		result->aps[i].signal = site_survey_array[i].rssi;

		if (strcmp(site_survey_array[i].ext_ch, "ABOVE") == 0) {
			result->aps[i].ext_channel = eWLAN_EXT_CHANNEL_ABOVE;
		} else if (strcmp(site_survey_array[i].ext_ch, "BELOW") == 0) {
			result->aps[i].ext_channel = eWLAN_EXT_CHANNEL_BELOW;
		} else {
			result->aps[i].ext_channel = eWLAN_EXT_CHANNEL_NONE;
		}

		if (dp_if->type == eDP_IF_TYPE_WLAN24G_CLI) {
			if (strcmp(site_survey_array[i].apmode, "11b") == 0) {
				result->aps[i].mode = eWLAN24G_MODE_B_ONLY;
			} else if (strcmp(site_survey_array[i].apmode, "11b/g") == 0) {
				result->aps[i].mode = eWLAN24G_MODE_BG_MIX;
			} else if (strcmp(site_survey_array[i].apmode, "11b/g/n") == 0) {
				result->aps[i].mode = eWLAN24G_MODE_BGN_MIX;
			} else {
				result->aps[i].mode = eWLAN24G_MODE_UNKNOWN;
			}
		} else {
			if (strcmp(site_survey_array[i].apmode, "11a") == 0) {
				result->aps[i].mode = eWLAN5G_MODE_A_ONLY;
			} else if (strcmp(site_survey_array[i].apmode, "11a/n") == 0) {
				result->aps[i].mode = eWLAN5G_MODE_AN_MIX;
			} else if (strcmp(site_survey_array[i].apmode, "11a/n/ac") == 0) {
				result->aps[i].mode = eWLAN5G_MODE_ANAC_MIX;
			} else {
				result->aps[i].mode = eWLAN5G_MODE_UNKNOWN;
			}
		}

		if (strcmp(site_survey_array[i].net_type, "Ad") == 0) {
			result->aps[i].network_type = eWLAN_NETWORK_TYPE_ADHOC;
		} else {
			result->aps[i].network_type = eWLAN_NETWORK_TYPE_INFRASTRUCTURE;
		}

		if (strcmp(site_survey_array[i].wps, "YES") == 0) {
			result->aps[i].wps = eBOOL_TRUE;
		} else {
			result->aps[i].wps = eBOOL_FALSE;
		}

		if (result->aps[i].wps) {
			if (strcmp(site_survey_array[i].dpid, "PBC") == 0) {
				result->aps[i].dpid = eWLAN_WPS_DPID_PBC;
			} else if (strcmp(site_survey_array[i].dpid, "PIN") == 0) {
				result->aps[i].dpid = eWLAN_WPS_DPID_PIN;
			} else {
				result->aps[i].dpid = eWLAN_WPS_DPID_NOT_SPEC;
			}
		} else {
			result->aps[i].dpid = eWLAN_WPS_DPID_NOT_SPEC;
		}

		item_start = site_survey_array[i].security;
		item_end = strchr(item_start, '/');
		if (item_end != NULL) {
			item_size = item_end - item_start;
			str_safe_cpy(authtype, item_start, item_size);
			item_start = item_end + 1;
			strcpy(encryptype, item_start);
		} else {
			sscanf(site_survey_array[i].security, "%s", encryptype);
			strcpy(authtype, "OPEN");
		}

		if (strcmp(encryptype, "NONE") == 0) {
			result->aps[i].enc_method = eWLAN_ENC_METHOD_NONE;
		} else if (strcmp(encryptype, "WEP") == 0) {
			result->aps[i].enc_method = eWLAN_ENC_METHOD_WEP;
		} else if (strcmp(encryptype, "TKIP") == 0) {
			result->aps[i].enc_method = eWLAN_ENC_METHOD_TKIP;
		} else if (strcmp(encryptype, "AES") == 0) {
			result->aps[i].enc_method = eWLAN_ENC_METHOD_AES;
		} else if (strcmp(encryptype, "TKIPAES") == 0) {
			result->aps[i].enc_method = eWLAN_ENC_METHOD_TKIP_AES;
		} else {
			result->aps[i].enc_method = eWLAN_ENC_METHOD_INVALID;
		}

		if (strcmp(authtype, "OPEN") == 0) {
			result->aps[i].auth_mode = eWLAN_AUTH_MODE_OPEN;
		} else if (strcmp(authtype, "SHARED") == 0) {
			result->aps[i].auth_mode = eWLAN_AUTH_MODE_SHARED;
		} else if (strcmp(authtype, "AUTOWEP") == 0) {
			result->aps[i].auth_mode = eWLAN_AUTH_MODE_WEPAUTO;
		} else if (strcmp(authtype, "WPA") == 0) {
			result->aps[i].auth_mode = eWLAN_AUTH_MODE_WPA;
		} else if (strcmp(authtype, "WPAPSK") == 0) {
			result->aps[i].auth_mode = eWLAN_AUTH_MODE_WPAPSK;
		} else if (strcmp(authtype, "WPA2") == 0) {
			result->aps[i].auth_mode = eWLAN_AUTH_MODE_WPA2;
		} else if (strcmp(authtype, "WPA2PSK") == 0) {
			result->aps[i].auth_mode = eWLAN_AUTH_MODE_WPA2PSK;
		} else if (strcmp(authtype, "WPA1WPA2") == 0) {
			result->aps[i].auth_mode = eWLAN_AUTH_MODE_WPAWPA2;
		} else if (strcmp(authtype, "WPA1PSKWPA2PSK") == 0) {
			result->aps[i].auth_mode = eWLAN_AUTH_MODE_WPAPSKWPA2PSK;
		} else {
			result->aps[i].auth_mode = eWLAN_AUTH_MODE_INVALID;
		}

#if 0
		sysmgr_dbg("-------- -------- -------- -------- -------- --------\n");
		sysmgr_dbg("ssid:%s\n", result->aps[i].ssid);
		sysmgr_dbg("channel:%d\n", result->aps[i].channel);
		sysmgr_dbg("ext_channel:%d\n", result->aps[i].ext_channel);
		sysmgr_dbg("mac:%s\n", result->aps[i].bssid);
		sysmgr_dbg("encrytype:%d\n", result->aps[i].enc_method);
		sysmgr_dbg("auth_type:%d\n", result->aps[i].auth_mode);
		sysmgr_dbg("signal:%d%%\n", result->aps[i].signal);
		sysmgr_dbg("w_mode:%d\n", result->aps[i].mode);
		sysmgr_dbg("NT:%d\n", result->aps[i].network_type);
		sysmgr_dbg("wps:%d\n", result->aps[i].wps);
		sysmgr_dbg("spid:%d\n\n", result->aps[i].dpid);
#endif
	}

	sysmgr_dbg("if[%s] result[%p] counter: %d scaning done.;\n", dp_if->name, result, result->counter);

	ret = eRET_SUCCESS;

out:

	*aps = result;
	if (sockfd >= 0) {
		close(sockfd);
	}

	return (ret);

}

e_ret pf_dep_wlancli_get_linkstatus(tdp_if * dp_if, twlan_cli_if_link_status ** aps)
{

	int rc;
	int fd;
	e_ret ret;
	const char *status_file;
	char status_buf[1024];
	twlan_cli_if_link_status *hostap;
	twlan_cli_if_linkcfg *linkcfg;

	fd = -1;
	ret = eRET_SUCCESS;

	hostap = malloc(sizeof(twlan_cli_if_link_status) + sizeof(twlan_cli_if_link_entry));
	if (hostap == NULL) {
		ret = eRET_NO_RESOURCE;
		goto out;
	}

	linkcfg = (twlan_cli_if_linkcfg *) dp_if->linkcfg;

	memset(hostap, 0, (sizeof(twlan_cli_if_link_status) + sizeof(twlan_cli_if_link_entry)));

	hostap->counter = 1;
	hostap->aps[0].auth_mode = linkcfg->auth_mode;
	hostap->aps[0].enc_method = linkcfg->enc_method;
	hostap->aps[0].channel = linkcfg->channel;
	hostap->aps[0].linked = eBOOL_FALSE;
	memcpy(hostap->aps[0].bssid, linkcfg->mac, sizeof(hostap->aps[0].bssid));
	memcpy(hostap->aps[0].ssid, linkcfg->ssid, sizeof(hostap->aps[0].ssid));

	rc = do_iwpriv(dp_if->name, "show", "connStatus");
	if (rc != 0) {
		sysmgr_err("do_iwpriv(%s, show, connStatus) failed, rc: %d\n", dp_if->name, rc);
		goto out;
	}

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_CLI) {
		status_file = WLAN_24G_CLI_CONN_STATUS_FILE;
	} else {
		status_file = WLAN_5G_CLI_CONN_STATUS_FILE;
	}

	fd = open(status_file, O_RDONLY);
	if (fd < 0) {
		sysmgr_err("open(%s, OWRONLY) failed, err: %d, [%s]\n", status_file, errno, strerror(errno));
		goto out;
	}

	rc = read(fd, status_buf, sizeof(status_buf));
	if (rc < 0) {
		sysmgr_err("read(%d) failed, err: %d, [%s]\n", fd, errno, strerror(errno));
		goto out;
	}

	if (strcasestr(status_buf, "Disconnect") != NULL) {
		hostap->aps[0].linked = eBOOL_FALSE;
	} else {
		int apcli_idx;
		int signal;
		unsigned long tx_rate;
		unsigned long rx_rate;
		char bssid[RC_MAC_STR_MAX_SIZE];
		char ssid[WLAN_SSID_SIZE];

		/* connected. */
		hostap->aps[0].linked = eBOOL_TRUE;

		/*
		 ** [ApCli0 Connected AP:74:D0:2B:64:F9:02 SSID:ASUS_Guest1 Signal:100 TxSpeed:130000000 RxSpeed:1000000]
		 */
		sscanf(status_buf, "ApCli%d Connected AP:%s SSID:%s "
		       "Signal:%d TxSpeed:%lu RxSpeed:%lu\n", &apcli_idx, bssid, ssid, &signal, &tx_rate, &rx_rate);
		str_safe_cpy(hostap->aps[0].bssid, bssid, RC_MAC_STR_MAX_SIZE - 1);
		str_safe_cpy(hostap->aps[0].ssid, ssid, WLAN_SSID_SIZE - 1);
		hostap->aps[0].signal = signal;
		hostap->aps[0].tx_rate = tx_rate;
		hostap->aps[0].rx_rate = rx_rate;
	}

out:
	*aps = hostap;

	if (fd >= 0) {
		close(fd);
	}
	return (ret);

}

e_ret pf_dep_wlanap_set_ssid(tdp_if * dp_if, char *ssid, e_bool * reset)
{
	char iwpriv_arg[128];
	int rc = -1;

	sysmgr_dbg("if[%s], set SSID -> [%s]\n", dp_if->name, ssid);
	sprintf(iwpriv_arg, "%s=%s", WLAN_AP_SSID_KEY, ssid);
	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0)
		goto rtuser_exit;

	*reset = eBOOL_TRUE;
	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP1_SSID_KEY, ssid);
	} else {
		pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP1_SSID_KEY, ssid);
	}

rtuser_exit:
	if (rc < 0)
		return (eRET_FAILURE);
	else
		return (eRET_SUCCESS);
}

e_ret pf_dep_wlanap_set_sec_stuff(tdp_if * dp_if, unsigned char auth_mode,
				  unsigned char enc_method, twlan_sec_key * sec_key, e_bool * reset)
{

	twlan_ap_if_linkcfg *linkcfg;
	char iwpriv_arg[128];
	char var_auth[32], var_enc[32], var_wpamix[32], var_defkeyid[4];
	int rc = -1;
	int cfg_idx;
	int key_len;

	sysmgr_dbg("if[%s], set: AuthMode -> [%u]; EncryptType -> [%u];\n", dp_if->name, auth_mode, enc_method);

	/* Sanity Check */
	switch (auth_mode) {
	case eWLAN_AUTH_MODE_OPEN:
		if ((enc_method != eWLAN_ENC_METHOD_NONE) && (enc_method != eWLAN_ENC_METHOD_WEP)) {
			sysmgr_err("Invalid EncrypType:%d for Auth:%d\n", enc_method, auth_mode);
			return (eRET_INVALID_ARG);
		}

		if (enc_method == eWLAN_ENC_METHOD_WEP) {
			sysmgr_dbg("key default id [%u]:\n"
				   "1: value: [%s]\n"
				   "2: value: [%s]\n"
				   "3: value: [%s]\n"
				   "4: value: [%s]\n",
				   sec_key->wep_key.default_id,
				   sec_key->wep_key.key[0].value,
				   sec_key->wep_key.key[1].value,
				   sec_key->wep_key.key[2].value, sec_key->wep_key.key[3].value);
			key_len = strlen(sec_key->wep_key.key[sec_key->wep_key.default_id - 1].value);
			if ((key_len != 5) && (key_len != 10) && (key_len != 13) && (key_len != 26)) {
				sysmgr_err("Invalid Key Length:%d\n", key_len);
				return (eRET_INVALID_ARG);
			}
		}
		break;

	case eWLAN_AUTH_MODE_SHARED:
	case eWLAN_AUTH_MODE_WEPAUTO:
		if (enc_method != eWLAN_ENC_METHOD_WEP) {
			sysmgr_err("Invalid EncrypType:%d for Auth:%d\n", enc_method, auth_mode);
			return (eRET_INVALID_ARG);
		}
		sysmgr_dbg("key default id [%u]:\n"
			   "1: value: [%s]\n"
			   "2: value: [%s]\n"
			   "3: value: [%s]\n"
			   "4: value: [%s]\n",
			   sec_key->wep_key.default_id,
			   sec_key->wep_key.key[0].value,
			   sec_key->wep_key.key[1].value, sec_key->wep_key.key[2].value, sec_key->wep_key.key[3].value);
		key_len = strlen(sec_key->wep_key.key[sec_key->wep_key.default_id - 1].value);
		if ((key_len != 5) && (key_len != 10) && (key_len != 13) && (key_len != 26)) {
			sysmgr_err("Invalid Key Length:%d\n", key_len);
			return (eRET_INVALID_ARG);
		}
		break;
	case eWLAN_AUTH_MODE_WPAPSK:
	case eWLAN_AUTH_MODE_WPA2PSK:
		sysmgr_dbg("key[%s];\n", sec_key->wpa_psk);
		if ((enc_method != eWLAN_ENC_METHOD_TKIP) && (enc_method != eWLAN_ENC_METHOD_AES)) {
			sysmgr_err("Invalid EncrypType:%d for Auth:%d\n", enc_method, auth_mode);
			return (eRET_INVALID_ARG);
		}
		key_len = strlen(sec_key->wpa_psk);
		if ((key_len < 8) || (key_len > 64)) {
			sysmgr_err("Invalid Key Length:%d\n", key_len);
			return (eRET_INVALID_ARG);
		}
		break;
	case eWLAN_AUTH_MODE_WPAPSKWPA2PSK:
		sysmgr_dbg("key[%s];\n", sec_key->wpa_psk);
		if (enc_method != eWLAN_ENC_METHOD_TKIP_AES) {
			sysmgr_err("Invalid EncrypType:%d for Auth:%d\n", enc_method, auth_mode);
			return (eRET_INVALID_ARG);
		}
		key_len = strlen(sec_key->wpa_psk);
		if ((key_len < 8) || (key_len > 64)) {
			sysmgr_err("Invalid Key Length:%d\n", key_len);
			return (eRET_INVALID_ARG);
		}
		break;

	case eWLAN_AUTH_MODE_WPA:
		break;
	case eWLAN_AUTH_MODE_WPA2:
		break;
	case eWLAN_AUTH_MODE_WPAWPA2:
		break;

	case eWLAN_AUTH_MODE_WPANONE:
	default:
		sysmgr_err("Invalid AuthMode:%d\n", auth_mode);
		return (eRET_INVALID_ARG);
	}

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		cfg_idx = RT2860_NVRAM;
	} else {
		cfg_idx = RTDEV_NVRAM;
	}

	authmode_to_pd_dep_authmode(auth_mode, var_auth);
	enctype_to_pd_dep_enctype(enc_method, auth_mode, var_enc, var_wpamix);

	switch (enc_method) {
	case eWLAN_ENC_METHOD_NONE:
		break;

	case eWLAN_ENC_METHOD_WEP:
		sprintf(iwpriv_arg, "%s=%u", WLAN_AP_ENC_WEP_DEFAULT_KEY_ID_KEY, sec_key->wep_key.default_id);
		sprintf(var_defkeyid, "%u", sec_key->wep_key.default_id);
		rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
		if (rc < 0) {
			return (eRET_FAILURE);
		}
		pf_dep_cfg_set_val(cfg_idx, WLAN_AP_ENC_WEP_DEFAULT_KEY_ID_KEY, var_defkeyid);

		key_len = strlen(sec_key->wep_key.key[0].value);
		if ((key_len == 5) || (key_len == 10) || (key_len == 13) || (key_len == 26)) {

			sprintf(iwpriv_arg, "%s=%s", WLAN_AP_ENC_WEP_KEY1_KEY, sec_key->wep_key.key[0].value);
			rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
			if (rc < 0) {
				return (eRET_FAILURE);
			}
			pf_dep_cfg_set_val(cfg_idx, WLAN_AP1_ENC_WEP_KEY1_STR_KEY, sec_key->wep_key.key[0].value);
			pf_dep_cfg_set_val(cfg_idx, WLAN_AP_ENC_WEP_KEY1_TYPE_KEY,
					   (((key_len == 5) || (key_len == 13)) ? "1" : "0"));
		}

		key_len = strlen(sec_key->wep_key.key[1].value);
		if ((key_len == 5) || (key_len == 10) || (key_len == 13) || (key_len == 26)) {

			sprintf(iwpriv_arg, "%s=%s", WLAN_AP_ENC_WEP_KEY2_KEY, sec_key->wep_key.key[1].value);
			rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
			if (rc < 0) {
				return (eRET_FAILURE);
			}
			pf_dep_cfg_set_val(cfg_idx, WLAN_AP1_ENC_WEP_KEY2_STR_KEY, sec_key->wep_key.key[1].value);
			pf_dep_cfg_set_val(cfg_idx, WLAN_AP_ENC_WEP_KEY2_TYPE_KEY,
					   (((key_len == 5) || (key_len == 13)) ? "1" : "0"));
		}

		key_len = strlen(sec_key->wep_key.key[2].value);
		if ((key_len == 5) || (key_len == 10) || (key_len == 13) || (key_len == 26)) {

			sprintf(iwpriv_arg, "%s=%s", WLAN_AP_ENC_WEP_KEY3_KEY, sec_key->wep_key.key[2].value);
			rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
			if (rc < 0) {
				return (eRET_FAILURE);
			}
			pf_dep_cfg_set_val(cfg_idx, WLAN_AP1_ENC_WEP_KEY3_STR_KEY, sec_key->wep_key.key[2].value);
			pf_dep_cfg_set_val(cfg_idx, WLAN_AP_ENC_WEP_KEY3_TYPE_KEY,
					   (((key_len == 5) || (key_len == 13)) ? "1" : "0"));
		}

		key_len = strlen(sec_key->wep_key.key[3].value);
		if ((key_len == 5) || (key_len == 10) || (key_len == 13) || (key_len == 26)) {

			sprintf(iwpriv_arg, "%s=%s", WLAN_AP_ENC_WEP_KEY4_KEY, sec_key->wep_key.key[3].value);
			rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
			if (rc < 0) {
				return (eRET_FAILURE);
			}
			pf_dep_cfg_set_val(cfg_idx, WLAN_AP1_ENC_WEP_KEY4_STR_KEY, sec_key->wep_key.key[3].value);
			pf_dep_cfg_set_val(cfg_idx, WLAN_AP_ENC_WEP_KEY4_TYPE_KEY,
					   (((key_len == 5) || (key_len == 13)) ? "1" : "0"));
		}
		break;

	case eWLAN_ENC_METHOD_TKIP:
	case eWLAN_ENC_METHOD_AES:
	case eWLAN_ENC_METHOD_TKIP_AES:
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_ENC_WPAPSK_KEY, sec_key->wpa_psk);
		rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
		if (rc < 0) {
			return (eRET_FAILURE);
		}
		pf_dep_cfg_set_val(cfg_idx, WLAN_AP1_ENC_WPAPSK_KEY, sec_key->wpa_psk);
		break;
	}

	if (auth_mode != eWLAN_AUTH_MODE_WPAPSKWPA2PSK) {
		if (var_auth[0] != 0) {
			sprintf(iwpriv_arg, "%s=%s", WLAN_AP_AUTH_MODE_KEY, var_auth);
			rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
			if (rc < 0) {
				return (eRET_FAILURE);
			}
			pf_dep_cfg_set_val(cfg_idx, WLAN_AP_AUTH_MODE_KEY, var_auth);
		}

		if (var_enc[0] != 0) {
			sprintf(iwpriv_arg, "%s=%s", WLAN_AP_ENC_TYPE_KEY, var_enc);
			rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
			if (rc < 0) {
				return (eRET_FAILURE);
			}
			pf_dep_cfg_set_val(cfg_idx, WLAN_AP_ENC_TYPE_KEY, var_enc);
		}
		pf_dep_cfg_set_val(cfg_idx, WLAN_AP_ENC_WPA_MIX_KEY, "");
	} else {
		if (var_wpamix[0] != 0) {
			sprintf(iwpriv_arg, "%s=%s", WLAN_AP_ENC_WPA_MIX_KEY, var_wpamix);
			rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
			if (rc < 0) {
				return (eRET_FAILURE);
			}
			pf_dep_cfg_set_val(cfg_idx, WLAN_AP_ENC_WPA_MIX_KEY, var_wpamix);
		}
	}

	/* Need set SSID to complete setting. */
	linkcfg = dp_if->linkcfg;
	if ((linkcfg == NULL) || (linkcfg->ssid[0] == 0)) {
		if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
			sprintf(iwpriv_arg, "%s=%s", WLAN_AP_SSID_KEY, DEFAULT_WLAN_24G_AP_SSID);
		} else {
			sprintf(iwpriv_arg, "%s=%s", WLAN_AP_SSID_KEY, DEFAULT_WLAN_5G_AP_SSID);
		}
	} else {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_SSID_KEY, linkcfg->ssid);
	}
	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0) {
		return (eRET_FAILURE);
	}
	*reset = eBOOL_TRUE;

	return (eRET_SUCCESS);

}

e_ret pf_dep_wlanap_set_mode(tdp_if * dp_if, unsigned char mode)
{
	char cfg_mode_val[4];
	char iwpriv_arg[128];
	int rc = -1;

	sysmgr_dbg("if[%s], set Mode -> [%d]\n", dp_if->name, mode);

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		wlmode_to_pd_dep_wlmode_24g(mode, cfg_mode_val);
	} else {
		wlmode_to_pd_dep_wlmode_5g(mode, cfg_mode_val);
	}

	sprintf(iwpriv_arg, "%s=%s", WLAN_AP_WL_MODE_KEY, cfg_mode_val);
	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc != 0) {
		return (eRET_FAILURE);
	}
	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP_WL_MODE_KEY, cfg_mode_val);
	} else {
		pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_WL_MODE_KEY, cfg_mode_val);
	}

	return (eRET_SUCCESS);

}

e_ret pf_dep_wlanap_set_bw(tdp_if * dp_if, unsigned char bw)
{
	int rc;
	char iwpriv_arg[128], var_htbw[32], var_vhtbw[32];

	sysmgr_dbg("if[%s], set BandWidth -> [%d]\n", dp_if->name, bw);

	bw_to_pd_dep_bw(bw, var_htbw, var_vhtbw);
	sprintf(iwpriv_arg, "%s=%s", WLAN_AP_HTBW_KEY, var_htbw);
	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0) {
		return (eRET_FAILURE);
	}

	if (dp_if->type == eDP_IF_TYPE_WLAN5G_AP) {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_VHTBW_KEY, var_vhtbw);
		rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
		if (rc < 0) {
			return (eRET_FAILURE);
		}
	}

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP_HTBW_CFG_KEY, var_htbw);
		pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP_VHTBW_CFG_KEY, var_vhtbw);
	} else {
		pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_HTBW_CFG_KEY, var_htbw);
		pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_VHTBW_CFG_KEY, var_vhtbw);
	}

	return (eRET_SUCCESS);

}

e_ret pf_dep_wlanap_set_sgi(tdp_if * dp_if, e_bool sgi)
{
	char iwpriv_arg[128], var_sgi[32];
	int rc = -1;

	sysmgr_dbg("if[%s], set SGI -> [%d]\n", dp_if->name, sgi);

	if (sgi == eBOOL_FALSE) {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_SGI_KEY, "0");
		sprintf(var_sgi, "%d", sgi);
	} else {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_SGI_KEY, "1");
		sprintf(var_sgi, "%d", sgi);
	}

	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0) {
		return (eRET_FAILURE);
	}

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP_SGI_CFG_KEY, var_sgi);
	} else {
		pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_SGI_CFG_KEY, var_sgi);
		pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_VHT_SGI_CFG_KEY, var_sgi);
	}

	return (eRET_SUCCESS);
}

e_ret pf_dep_wlanap_set_txpwr(tdp_if * dp_if, unsigned char txpwr)
{

	char iwpriv_arg[128], var_txpwr[32];
	int rc = -1;

	sysmgr_dbg("if[%s], set Tx Power -> [%d]\n", dp_if->name, txpwr);

	sprintf(iwpriv_arg, "%s=%u", WLAN_AP_TXPOWER_KEY, txpwr);
	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0) {
		return (eRET_FAILURE);
	}

	sprintf(var_txpwr, "%u", txpwr);
	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP_TXPOWER_KEY, var_txpwr);
	} else {
		pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_TXPOWER_KEY, var_txpwr);
	}

	return (eRET_SUCCESS);

}

e_ret pf_dep_wlanap_set_channel(tdp_if * dp_if, unsigned short channel, e_bool * reset)
{
	char const *val;
	char iwpriv_arg[128], var_chan[32];
	int rc = -1;

	sysmgr_dbg("if[%s], set Channel -> [%d]\n", dp_if->name, channel);

	if (channel == 0) {
		/* Auto select, need update XXXX.DAT file and re-init the interface. */
		if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
			val = pf_dep_cfg_get_val(RT2860_NVRAM, WLAN_AP_AUTO_CH_SEL_KEY, "");
			if (val[0] != '1') {
				pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP_CHANNEL_KEY, DEFAULT_WLAN_24G_AP_CHANNEL);
				pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP_AUTO_CH_SEL_KEY,
						   DEFAULT_WLAN_24G_AP_AUTO_CHANNEL);
				*reset = eBOOL_TRUE;
			}
		} else {
			val = pf_dep_cfg_get_val(RTDEV_NVRAM, WLAN_AP_AUTO_CH_SEL_KEY, "");
			if (val[0] != '1') {
				pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_CHANNEL_KEY, DEFAULT_WLAN_5G_AP_CHANNEL);
				pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_AUTO_CH_SEL_KEY,
						   DEFAULT_WLAN_5G_AP_AUTO_CHANNEL);
				*reset = eBOOL_TRUE;
			}
		}
		return (eRET_SUCCESS);
	} else {
		sprintf(iwpriv_arg, "%s=%u", WLAN_AP_CHANNEL_KEY, channel);
		rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
		if (rc < 0) {
			return (eRET_FAILURE);
		}

		sprintf(var_chan, "%u", channel);
		if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
			pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP_CHANNEL_KEY, var_chan);
			pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP_AUTO_CH_SEL_KEY, "0");
		} else {
			pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_CHANNEL_KEY, var_chan);
			pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_AUTO_CH_SEL_KEY, "0");
		}
	}

	return (eRET_SUCCESS);

}

e_ret pf_dep_wlanap_set_beacon_interval(tdp_if * dp_if, unsigned short beacon_interval)
{
	char iwpriv_arg[128], var_bea[32];
	int rc = -1;

	sysmgr_dbg("if[%s], set Beacon Interval -> [%d]\n", dp_if->name, beacon_interval);

	sprintf(iwpriv_arg, "%s=%u", WLAN_AP_BEACON_PERIOD_KEY, beacon_interval);
	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0) {
		return (eRET_FAILURE);
	}

	sprintf(var_bea, "%u", beacon_interval);
	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP_BEACON_PERIOD_KEY, var_bea);
	} else {
		pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_BEACON_PERIOD_KEY, var_bea);
	}

	return (eRET_SUCCESS);

}

e_ret pf_dep_wlanap_set_hide_ssid(tdp_if * dp_if, e_bool hide_ssid)
{
	char iwpriv_arg[128], var_hid_ssid[32];
	int rc = -1;

	sysmgr_dbg("if[%s], set Hide SSID -> [%d]\n", dp_if->name, hide_ssid);

	if (hide_ssid == eBOOL_TRUE) {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_HIDE_SSID_KEY, "1");
		sprintf(var_hid_ssid, "1");
	} else {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_HIDE_SSID_KEY, "0");
		sprintf(var_hid_ssid, "0");
	}

	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0) {
		return (eRET_FAILURE);
	}

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP_HIDE_SSID_KEY, var_hid_ssid);
	} else {
		pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_HIDE_SSID_KEY, var_hid_ssid);
	}

	return (eRET_SUCCESS);

}

e_ret pf_dep_wlanap_set_sta_isolate(tdp_if * dp_if, e_bool sta_isolate)
{

	char iwpriv_arg[128], var_sta_isolate[32];
	int rc = -1;

	sysmgr_dbg("if[%s], set Station Isolate -> [%d]\n", dp_if->name, sta_isolate);

	if (sta_isolate == eBOOL_TRUE) {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_STA_ISOLATE_KEY, "1");
		sprintf(var_sta_isolate, "1");
	} else {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_STA_ISOLATE_KEY, "0");
		sprintf(var_sta_isolate, "0");
	}

	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0) {
		return (eRET_FAILURE);
	}

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP_STA_ISOLATE_KEY, var_sta_isolate);
	} else {
		pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_STA_ISOLATE_KEY, var_sta_isolate);
	}

	return (eRET_SUCCESS);
}

e_ret pf_dep_wlanap_set_acl(tdp_if * dp_if, twlan_ap_acl * acl)
{
	int i, rc = -1;
	char acl_mac[1024] = { 0 }, iwpriv_arg[1024], var_acl_type[32];
	const char *var_mac;

	sysmgr_dbg("if[%s], set ACL: mode -> [%d], counter -> [%d]\n", dp_if->name, acl->acl_type, acl->counter);
	for (i = 0; i < acl->counter; i++) {
		sysmgr_dbg("\tACL %02d: [%s]\n", i, acl->acl[i].mac);
	}

	if (acl->acl_type == eWLAN_ACL_BLACKLIST) {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_ACCESS_POLICY_KEY, "2");
		sprintf(var_acl_type, "%d", eWLAN_ACL_BLACKLIST);
	} else if (acl->acl_type == eWLAN_ACL_WHITELIST) {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_ACCESS_POLICY_KEY, "1");
		sprintf(var_acl_type, "%d", eWLAN_ACL_WHITELIST);
	} else {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_ACCESS_POLICY_KEY, "0");
		sprintf(var_acl_type, "%d", eWLAN_ACL_NONE);
	}
	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0)
		goto rtuser_exit;

	for (i = 0; i < acl->counter; i++) {
		strcat(acl_mac, acl->acl[i].mac);
		if (i + 1 < acl->counter) {
			strcat(acl_mac, ";");
		}
	}

	sprintf(iwpriv_arg, "%s=%s", WLAN_AP_ACL_CLEAR_ALL_KEY, "1");
	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0)
		goto rtuser_exit;

	sprintf(iwpriv_arg, "%s=%s", WLAN_AP_ACL_ADD_ENTRY_KEY, acl_mac);
	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0)
		goto rtuser_exit;

	if (acl->acl_type == eWLAN_ACL_NONE) {
		if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
			var_mac = pf_dep_cfg_get_val(RT2860_NVRAM, WLAN_AP1_ACL_STRING_KEY, "");
		} else {
			var_mac = pf_dep_cfg_get_val(RTDEV_NVRAM, WLAN_AP1_ACL_STRING_KEY, "");
		}
		strcpy(acl_mac, var_mac);
	}

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP1_ACCESS_POLICY_KEY, var_acl_type);
		pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP1_ACL_STRING_KEY, acl_mac);
	} else {
		pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP1_ACCESS_POLICY_KEY, var_acl_type);
		pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP1_ACL_STRING_KEY, acl_mac);
	}

rtuser_exit:
	if (rc < 0)
		return (eRET_FAILURE);
	else
		return (eRET_SUCCESS);
}

e_ret pf_dep_wlanap_set_wmm_apsd_dls(tdp_if * dp_if, e_bool wmm_apsd, e_bool wmm_dls, e_bool * reset)
{

	e_bool need_reset;
	const char *val;
	char var_wmm_apsd[32], var_wmm_dls[32];

	sysmgr_dbg("if[%s], set Station APSDCapable -> [%d], DLSCapable -> [%d]\n", dp_if->name, wmm_apsd, wmm_dls);

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		need_reset = eBOOL_FALSE;
		if (wmm_apsd == eBOOL_TRUE) {
			sprintf(var_wmm_apsd, "1");
		} else {
			sprintf(var_wmm_apsd, "0");
		}
		val = pf_dep_cfg_get_val(RT2860_NVRAM, WLAN_AP_APSD_CAPABLE, DEFAULT_WLAN_24G_AP_APSD_CAPABLE);
		if (val[0] != var_wmm_apsd[0]) {
			need_reset = eBOOL_TRUE;
			pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP_APSD_CAPABLE, var_wmm_apsd);
		}

		if (wmm_dls == eBOOL_TRUE) {
			sprintf(var_wmm_dls, "1");
		} else {
			sprintf(var_wmm_dls, "0");
		}

		val = pf_dep_cfg_get_val(RT2860_NVRAM, WLAN_AP_DLS_CAPABLE, DEFAULT_WLAN_24G_AP_DLS_CAPABLE);
		if (val[0] != var_wmm_dls[0]) {
			need_reset = eBOOL_TRUE;
			pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP_DLS_CAPABLE, var_wmm_dls);
		}

		if (need_reset) {
			*reset = eBOOL_TRUE;
		}
	} else {
		need_reset = eBOOL_FALSE;
		if (wmm_apsd == eBOOL_TRUE) {
			sprintf(var_wmm_apsd, "1");
		} else {
			sprintf(var_wmm_apsd, "0");
		}
		val = pf_dep_cfg_get_val(RTDEV_NVRAM, WLAN_AP_APSD_CAPABLE, DEFAULT_WLAN_5G_AP_APSD_CAPABLE);
		if (val[0] != var_wmm_apsd[0]) {
			need_reset = eBOOL_TRUE;
			pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_APSD_CAPABLE, var_wmm_apsd);
		}
		if (wmm_dls == eBOOL_TRUE) {
			sprintf(var_wmm_dls, "1");
		} else {
			sprintf(var_wmm_dls, "0");
		}
		val = pf_dep_cfg_get_val(RTDEV_NVRAM, WLAN_AP_DLS_CAPABLE, DEFAULT_WLAN_5G_AP_DLS_CAPABLE);
		if (val[0] != var_wmm_dls[0]) {
			need_reset = eBOOL_TRUE;
			pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_DLS_CAPABLE, var_wmm_dls);
		}
		if (need_reset) {
			*reset = eBOOL_TRUE;
		}
	}

	return (eRET_SUCCESS);
}

e_ret pf_dep_wlanap_set_bgprotection(tdp_if * dp_if, unsigned short bg_protection)
{

	char iwpriv_arg[128], var_bgprotection[32];
	int rc = -1;

	sysmgr_dbg("if[%s], set Station bg_protection -> [%d]\n", dp_if->name, bg_protection);

	if (bg_protection == eWLAN_BG_PROTECT_AUTO) {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_BG_PROTECTION, "0");
		sprintf(var_bgprotection, "0");
	} else if (bg_protection == eWLAN_BG_PROTECT_ON) {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_BG_PROTECTION, "1");
		sprintf(var_bgprotection, "1");
	} else {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_BG_PROTECTION, "2");
		sprintf(var_bgprotection, "2");
	}

	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0) {
		return (eRET_FAILURE);
	}

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP_BG_PROTECTION, var_bgprotection);
	} else {
		pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_BG_PROTECTION, var_bgprotection);
	}

	return (eRET_SUCCESS);
}

e_ret pf_dep_wlanap_set_ht_extcha(tdp_if * dp_if, unsigned short ht_extcha)
{

	char iwpriv_arg[128], var_extcha[32];
	int rc = -1;

	sysmgr_dbg("if[%s], set Station ht_extcha -> [%d]\n", dp_if->name, ht_extcha);

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		if (ht_extcha == eWLAN_EXT_CHANNEL_BELOW) {
			sprintf(iwpriv_arg, "%s=%s", WLAN_AP_HT_EXTCHA, "0");
			sprintf(var_extcha, "0");
		} else if (ht_extcha == eWLAN_EXT_CHANNEL_ABOVE) {
			sprintf(iwpriv_arg, "%s=%s", WLAN_AP_HT_EXTCHA, "1");
			sprintf(var_extcha, "1");
		} else {
			return (eRET_SUCCESS);
		}

		rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
		if (rc < 0) {
			return (eRET_FAILURE);
		}

		pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP1_HT_EXTCHA, var_extcha);
	} else {
		sysmgr_dbg("5G if[%s], Do NOT Support This.\n", dp_if->name);
	}

	return (eRET_SUCCESS);
}

e_ret pf_dep_wlanap_set_rekey(tdp_if * dp_if, unsigned long rekey, e_bool * reset)
{

	e_bool need_reset;
	const char *val;
	char var_rekeytime[32];

	sysmgr_dbg("if[%s], set Station rekey -> [%ld]\n", dp_if->name, rekey);

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		need_reset = eBOOL_FALSE;
		if (rekey == 0) {
			sprintf(var_rekeytime, "0");
		} else {
			sprintf(var_rekeytime, "%ld", rekey);
		}
		val = pf_dep_cfg_get_val(RT2860_NVRAM, WLAN_AP_REKEY_INTERVAL, DEFAULT_WLAN_24G_AP_REKEY_INTERVAL);
		if (strcmp(val, var_rekeytime)) {
			need_reset = eBOOL_TRUE;
			pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP_REKEY_INTERVAL, var_rekeytime);
		}
		if (need_reset) {
			*reset = eBOOL_TRUE;
		}
	} else {
		need_reset = eBOOL_FALSE;
		if (rekey == 0) {
			sprintf(var_rekeytime, "0");
		} else {
			sprintf(var_rekeytime, "%ld", rekey);
		}
		val = pf_dep_cfg_get_val(RTDEV_NVRAM, WLAN_AP_REKEY_INTERVAL, DEFAULT_WLAN_5G_AP_REKEY_INTERVAL);
		if (strcmp(val, var_rekeytime)) {
			need_reset = eBOOL_TRUE;
			pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_REKEY_INTERVAL, var_rekeytime);
		}

		if (need_reset) {
			*reset = eBOOL_TRUE;
		}

	}

	return (eRET_SUCCESS);
}

e_ret pf_dep_wlanap_set_rtsthreshold(tdp_if * dp_if, unsigned int rtsthreshold)
{
	char iwpriv_arg[128], var_rtsthreshold[32];
	int rc = -1;

	sysmgr_dbg("if[%s], set RTSThreshold -> [%u]\n", dp_if->name, rtsthreshold);

	sprintf(iwpriv_arg, "%s=%u", WLAN_AP_RTSTHRESHOLD, rtsthreshold);
	sprintf(var_rtsthreshold, "%u", rtsthreshold);

	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0) {
		return (eRET_FAILURE);
	}

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP_RTSTHRESHOLD, var_rtsthreshold);
	} else {
		pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_RTSTHRESHOLD, var_rtsthreshold);
	}

	return (eRET_SUCCESS);
}

e_ret pf_dep_wlanap_set_fragthreshold(tdp_if * dp_if, unsigned int fragthreshold)
{
	char iwpriv_arg[128], var_fragthreshold[32];
	int rc = -1;

	sysmgr_dbg("if[%s], set FragThreshold -> [%u]\n", dp_if->name, fragthreshold);

	sprintf(iwpriv_arg, "%s=%u", WLAN_AP_FRAGTHRESHOLD, fragthreshold);
	sprintf(var_fragthreshold, "%u", fragthreshold);

	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0) {
		return (eRET_FAILURE);
	}

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP_FRAGTHRESHOLD, var_fragthreshold);
	} else {
		pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_FRAGTHRESHOLD, var_fragthreshold);
	}

	return (eRET_SUCCESS);
}

e_ret pf_dep_wlanap_set_dtimperiod(tdp_if * dp_if, unsigned char dtimperiod)
{
	char iwpriv_arg[128], var_dtimperiod[32];
	int rc = -1;

	sysmgr_dbg("if[%s], set DtimPeriod -> [%u]\n", dp_if->name, dtimperiod);

	sprintf(iwpriv_arg, "%s=%u", WLAN_AP_DTIMPERIOD, dtimperiod);
	sprintf(var_dtimperiod, "%u", dtimperiod);

	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0) {
		return (eRET_FAILURE);
	}

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP_DTIMPERIOD, var_dtimperiod);
	} else {
		pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_DTIMPERIOD, var_dtimperiod);
	}

	return (eRET_SUCCESS);
}

e_ret pf_dep_wlanap_set_txburst(tdp_if * dp_if, e_bool txburst)
{
	char iwpriv_arg[128], var_txburst[32];
	int rc = -1;

	sysmgr_dbg("if[%s], set TxBurst -> [%d]\n", dp_if->name, txburst);

	if (txburst == eBOOL_TRUE) {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_TXBURST, "1");
		sprintf(var_txburst, "1");
	} else {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_TXBURST, "0");
		sprintf(var_txburst, "0");
	}

	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0) {
		return (eRET_FAILURE);
	}

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP_TXBURST, var_txburst);
	} else {
		pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_TXBURST, var_txburst);
	}

	return (eRET_SUCCESS);
}

e_ret pf_dep_wlanap_set_pktaggregate(tdp_if * dp_if, e_bool pktaggregate)
{
	char iwpriv_arg[128], var_pktaggregate[32];
	int rc = -1;

	sysmgr_dbg("if[%s], set PktAggregate -> [%d]\n", dp_if->name, pktaggregate);

	if (pktaggregate == eBOOL_TRUE) {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_PKTAGGREGATE, "1");
		sprintf(var_pktaggregate, "1");
	} else {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_PKTAGGREGATE, "0");
		sprintf(var_pktaggregate, "0");
	}

	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0) {
		return (eRET_FAILURE);
	}

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP_PKTAGGREGATE, var_pktaggregate);
	} else {
		pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_PKTAGGREGATE, var_pktaggregate);
	}

	return (eRET_SUCCESS);
}

e_ret pf_dep_wlanap_set_greenap(tdp_if * dp_if, e_bool greenap)
{
	char iwpriv_arg[128], var_greenap[32];
	int rc = -1;

	sysmgr_dbg("if[%s], set GreenAP -> [%d]\n", dp_if->name, greenap);

	if (greenap == eBOOL_TRUE) {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_GREENAP, "1");
		sprintf(var_greenap, "1");
	} else {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_GREENAP, "0");
		sprintf(var_greenap, "0");
	}

	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0) {
		return (eRET_FAILURE);
	}

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP_GREENAP, var_greenap);
	} else {
		pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_GREENAP, var_greenap);
	}

	return (eRET_SUCCESS);
}

e_ret pf_dep_wlanap_set_greenfied(tdp_if * dp_if, e_bool greenfield)
{
	char iwpriv_arg[128], var_greenfield[32];
	int rc = -1;

	sysmgr_dbg("if[%s], set Greenfield -> [%d]\n", dp_if->name, greenfield);

	if (greenfield == eBOOL_TRUE) {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_GREENFIELD, "1");
		sprintf(var_greenfield, "1");
	} else {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_GREENFIELD, "0");
		sprintf(var_greenfield, "0");
	}

	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0) {
		return (eRET_FAILURE);
	}

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP1_GREENFIELD, var_greenfield);
	} else {
		pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP1_GREENFIELD, var_greenfield);
	}

	return (eRET_SUCCESS);
}

e_ret pf_dep_wlanap_set_radio_on(tdp_if * dp_if, e_bool radio_on)
{
	char iwpriv_arg[128], var_apenable[32];
	int rc = -1;

	sysmgr_dbg("if[%s], set radio_on -> [%d]\n", dp_if->name, radio_on);

	if (radio_on == eBOOL_TRUE) {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_RADIOON, "1");
		sprintf(var_apenable, "1");
	} else {
		sprintf(iwpriv_arg, "%s=%s", WLAN_AP_RADIOON, "0");
		sprintf(var_apenable, "0");
	}

	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0) {
		return (eRET_FAILURE);
	}

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_AP_RADIOON, var_apenable);
	} else {
		pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_AP_RADIOON, var_apenable);
	}

	return (eRET_SUCCESS);
}

e_ret pf_dep_wlanap_reset(tdp_if * dp_if)
{

	tdata_paths *dp = dp_if->data_paths;

	pf_dep_cfg_close();

	sysmgr_dbg("if[%s], set radio reset\n", dp_if->name);
	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		cleanup_wlan24g_cli_if(dp_if->data_paths);
		cleanup_wlan24g_ap_if(dp_if->data_paths);
		usleep(1000);
		init_rt2860v2_ap_dev(dp_if->based_on_dev);
		usleep(1000);
		init_wlan24g_ap_if(dp_if->data_paths);
		if ((dp != NULL) && (dp->mode == eDP_MODE_BRIDGE_REPEATER)) {
			init_wlan24g_cli_if(dp_if->data_paths);
		}
	} else {
		cleanup_wlan5g_cli_if(dp_if->data_paths);
		cleanup_wlan5g_ap_if(dp_if->data_paths);
		usleep(1000);
		init_rlt_wifi_dev(dp_if->based_on_dev);
		usleep(1000);
		init_wlan5g_ap_if(dp_if->data_paths);
		if ((dp != NULL) && (dp->mode == eDP_MODE_BRIDGE_REPEATER)) {
			init_wlan5g_cli_if(dp_if->data_paths);
		}
	}

	pf_dep_cfg_init();

	return (eRET_SUCCESS);
}

e_ret pf_dep_wlanap_get_linkstatus(tdp_if * dp_if, twlan_ap_if_link_status ** clients)
{
	e_ret ret;
	int i;
	int rc;
	int sockfd;
	int cli_counter;
	unsigned char bw;
	unsigned long txrate;
	unsigned long rxrate;
	RT_802_11_MAC_TABLE mac_table;
	HTTRANSMIT_SETTING_24G tx_rate_24g, rx_rate_24g;
	HTTRANSMIT_SETTING_5G tx_rate_5g, rx_rate_5g;
	twlan_ap_if_link_status *result;
	struct iwreq iwrq;

	sysmgr_dbg("if[%s] get station list;\n", dp_if->name);

	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if (sockfd < 0) {
		sysmgr_err("socket() failed, err: %d,[%s]\n", errno, strerror(errno));
		*clients = NULL;
		return (eRET_FAILURE);
	}

	cli_counter = 0;
	result = NULL;

	memset(&mac_table, 0x0, sizeof(mac_table));

	strcpy(iwrq.ifr_name, dp_if->name);
	iwrq.u.data.length = sizeof(mac_table);
	iwrq.u.data.pointer = &mac_table;
	iwrq.u.data.flags = 0;
	rc = ioctl(sockfd, RTPRIV_IOCTL_GET_MAC_TABLE_STRUCT, &iwrq);
	sysmgr_dbg("ioctl(%s, RTPRIV_IOCTL_GET_MAC_TABLE_STRUCT) num[%lu], rc: %d\n", dp_if->name, mac_table.Num, rc);
	if (rc < 0) {
		sysmgr_err("ioctl() failed, err: %d,[%s]\n", errno, strerror(errno));
		ret = eRET_FAILURE;
		goto out;
	}

	cli_counter = mac_table.Num;
	if (cli_counter == 0) {
		ret = eRET_SUCCESS;
		goto out;
	}

	result = malloc(sizeof(twlan_ap_if_link_status) + cli_counter * sizeof(twlan_ap_if_link_entry));
	if (result == NULL) {
		ret = eRET_NO_RESOURCE;
		goto out;
	}

	memset(result, 0x0, sizeof(twlan_ap_if_link_status) + cli_counter * sizeof(twlan_ap_if_link_entry));

	result->counter = cli_counter;

	for (i = 0; i < cli_counter; i++) {
		result->clients[i].online_time = mac_table.Entry[i].ConnectedTime;
		sprintf(result->clients[i].cli_mac.mac, "%02X:%02X:%02X:%02X:%02X:%02X",
			mac_table.Entry[i].Addr[0], mac_table.Entry[i].Addr[1],
			mac_table.Entry[i].Addr[2], mac_table.Entry[i].Addr[3],
			mac_table.Entry[i].Addr[4], mac_table.Entry[i].Addr[5]);
		result->clients[i].power_save = (mac_table.Entry[i].Psm == 0) ? eBOOL_FALSE : eBOOL_TRUE;

		if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
			tx_rate_24g.word = mac_table.Entry[i].TxRate;
			bw = tx_rate_24g.field.BW;
			mtk_wlan_get_bitrate(tx_rate_24g.field.MODE, tx_rate_24g.field.ShortGI,
					     tx_rate_24g.field.BW, tx_rate_24g.field.MCS, &txrate);
			rx_rate_24g.word = mac_table.Entry[i].LastRxRate;
			mtk_wlan_get_bitrate(rx_rate_24g.field.MODE, rx_rate_24g.field.ShortGI,
					     rx_rate_24g.field.BW, rx_rate_24g.field.MCS, &rxrate);
		} else {
			tx_rate_5g.word = mac_table.Entry[i].TxRate;
			bw = tx_rate_5g.field.BW;
			mtk_wlan_get_bitrate(tx_rate_5g.field.MODE, tx_rate_5g.field.ShortGI,
					     tx_rate_5g.field.BW, tx_rate_5g.field.MCS, &txrate);
			rx_rate_5g.word = mac_table.Entry[i].LastRxRate;
			mtk_wlan_get_bitrate(rx_rate_5g.field.MODE, rx_rate_5g.field.ShortGI,
					     rx_rate_5g.field.BW, rx_rate_5g.field.MCS, &rxrate);
		}

		result->clients[i].tx_rate = txrate;
		result->clients[i].rx_rate = rxrate;

		switch (bw) {
		case 0:
			result->clients[i].bw = eWLAN_BW_20M;
			break;
		case 1:
			result->clients[i].bw = eWLAN_BW_40M;
			break;
		case 2:
			result->clients[i].bw = eWLAN_BW_80M;
			break;
		case 3:
			/* Need check. */
			result->clients[i].bw = eWLAN_BW_40M_80M;
			break;
		}

		result->clients[i].rssi0 = mac_table.Entry[i].AvgRssi0;
		result->clients[i].rssi1 = mac_table.Entry[i].AvgRssi1;
		result->clients[i].rssi2 = mac_table.Entry[i].AvgRssi2;

		sysmgr_dbg("-------- -------- -------- -------- -------- --------\n");
		sysmgr_dbg("MAC:%s\n", result->clients[i].cli_mac.mac);
		sysmgr_dbg("PowerSave:%c\n", result->clients[i].power_save ? 'Y' : 'N');
		sysmgr_dbg("BW:%d\n", result->clients[i].bw);
		sysmgr_dbg("rssi0:%d\n", result->clients[i].rssi0);
		sysmgr_dbg("rssi1:%d\n", result->clients[i].rssi1);
		sysmgr_dbg("rssi2:%d\n", result->clients[i].rssi2);
		sysmgr_dbg("tx_rate:%ld.%ldMbit/s\n", (result->clients[i].tx_rate / (1000 * 1000)),
			   ((result->clients[i].tx_rate % (1000 * 1000)) / (100 * 1000)));
		sysmgr_dbg("rx_rate:%ld.%ldMbit/s\n", (result->clients[i].rx_rate / (1000 * 1000)),
			   ((result->clients[i].rx_rate % (1000 * 1000)) / (100 * 1000)));
	}

	sysmgr_dbg("if[%s] result[%p] counter: %d get station list done.\n", dp_if->name, result, result->counter);

	ret = eRET_SUCCESS;

out:

	*clients = result;

	if (sockfd >= 0) {
		close(sockfd);
	}

	return (ret);

}

e_ret pf_dep_ether_get_linkstatus(tdp_if * dp_if, teth_if_link_status ** status)
{

	teth_if_link_status *link_status;

	link_status = malloc(sizeof(*link_status));
	if (link_status == NULL) {
		sysmgr_err("malloc(%d) failed, err: %d,[%s]\n", sizeof(*link_status), errno, strerror(errno));
		*status = NULL;
		return (eRET_NO_RESOURCE);
	}

	link_status->linked = eBOOL_TRUE;
	link_status->speed = eETH_IF_LINK_SPEED_100M;
	link_status->dumplex = eETH_IF_LINK_DUMPLEX_FULL;

	*status = link_status;

	return (eRET_SUCCESS);
}

e_ret pf_dep_vlan_if_get_linkstatus(tdp_if * dp_if, teth_if_link_status ** status)
{

	int esw_fd;
	tvlan_if_linkcfg *linkcfg;
	teth_if_link_status *link_status;

	link_status = malloc(sizeof(*link_status));
	if (link_status == NULL) {
		sysmgr_err("malloc(%d) failed, err: %d,[%s]\n", sizeof(*link_status), errno, strerror(errno));
		*status = NULL;
		return (eRET_NO_RESOURCE);
	}

	linkcfg = dp_if->linkcfg;
	if (linkcfg != NULL) {
		if (linkcfg->vlan_id == 2) {
			int ret_val;
			link_status->linked = eBOOL_FALSE;
			link_status->dumplex = eETH_IF_LINK_DUMPLEX_HALF;
			link_status->speed = eETH_IF_LINK_SPEED_10M;

			esw_fd = raesw_init();
			if (esw_fd < 0) {
				return (eRET_FAILURE);
			}
			/* switch port 4 */
			raesw_reg_read(esw_fd, 0x3408, &ret_val);
			if (ret_val & 0x01) {
				link_status->linked = eBOOL_TRUE;
			}

			if (ret_val & 0x02) {
				link_status->dumplex = eETH_IF_LINK_DUMPLEX_FULL;
			}

			switch ((ret_val & 0xC) >> 2) {
			case 0:
				link_status->speed = eETH_IF_LINK_SPEED_10M;
				break;
			case 1:
				link_status->speed = eETH_IF_LINK_SPEED_100M;
				break;
			case 2:
				link_status->speed = eETH_IF_LINK_SPEED_1000M;
				break;
			case 3:
			default:
				link_status->speed = eETH_IF_LINK_SPEED_100M;
				break;
			}
			raesw_finish(esw_fd);
		} else {
			link_status->linked = eBOOL_TRUE;
			link_status->speed = eETH_IF_LINK_SPEED_100M;
			link_status->dumplex = eETH_IF_LINK_DUMPLEX_FULL;
		}
	} else {
		link_status->linked = eBOOL_TRUE;
		link_status->speed = eETH_IF_LINK_SPEED_100M;
		link_status->dumplex = eETH_IF_LINK_DUMPLEX_FULL;
	}

	*status = link_status;

	return (eRET_SUCCESS);
}

e_ret pf_dep_set_if_netcfg_conntype(tdp_if * dp_if, unsigned char conntype)
{

	char key[NVRAM_CFG_KEY_SIZE] = { 0 };
	char conntype_val[32];

	conntype_to_pf_dep_conntype(conntype, conntype_val);

	sprintf(key, NETCFG_CT_KEY, dp_if->name);
	pf_dep_cfg_set_val(RT2860_NVRAM, key, conntype_val);

	return (eRET_SUCCESS);
}

e_ret pf_dep_set_if_netcfg_pptp(tdp_if * dp_if, tpptp_netcfg * pptp_netcfg)
{
	char key[NVRAM_CFG_KEY_SIZE] = { 0 };

	return (eRET_NOT_SUPPORT);

	sprintf(key, CT_PPTP_USERNAME_KEY, dp_if->name);
	pf_dep_cfg_set_val(RT2860_NVRAM, key, pptp_netcfg->username);

	sprintf(key, CT_PPTP_PASSWORD_KEY, dp_if->name);
	pf_dep_cfg_set_val(RT2860_NVRAM, key, pptp_netcfg->password);

	sprintf(key, CT_PPTP_SERVERIP_KEY, dp_if->name);
	pf_dep_cfg_set_val(RT2860_NVRAM, key, pptp_netcfg->serverip);

	return (eRET_SUCCESS);
}

e_ret pf_dep_set_if_netcfg_pppoe(tdp_if * dp_if, tpppoe_netcfg * pppoe_netcfg)
{

	char key[NVRAM_CFG_KEY_SIZE] = { 0 };

	return (eRET_NOT_SUPPORT);

	switch (pppoe_netcfg->conntype) {
	case ePPPOE_CONN_TYPE_STAY:
		sprintf(key, CT_PPPOE_CONN_TYPE_KEY, dp_if->name);
		pf_dep_cfg_set_val(RT2860_NVRAM, key, CT_PPPOE_CONN_TYPE_STAY_VAL);
		break;
	case ePPPOE_CONN_TYPE_MANUAL:
	default:
		sprintf(key, CT_PPPOE_CONN_TYPE_KEY, dp_if->name);
		pf_dep_cfg_set_val(RT2860_NVRAM, key, CT_PPPOE_CONN_TYPE_MANUAL_VAL);
		break;
	}

	sprintf(key, CT_PPPOE_USERNAME_KEY, dp_if->name);
	pf_dep_cfg_set_val(RT2860_NVRAM, key, pppoe_netcfg->username);

	sprintf(key, CT_PPPOE_PASSWORD_KEY, dp_if->name);
	pf_dep_cfg_set_val(RT2860_NVRAM, key, pppoe_netcfg->password);

	return (eRET_SUCCESS);
}

e_ret pf_dep_set_if_netcfg_ppp(tdp_if * dp_if, tppp_modem_netcfg * ppp_netcfg)
{
	return (eRET_NOT_SUPPORT);
}

e_ret pf_dep_set_if_netcfg_static(tdp_if * dp_if, tstatic_netcfg * static_netcfg)
{

	char key[NVRAM_CFG_KEY_SIZE] = { 0 };

	sprintf(key, CT_STATIC_IP_KEY, dp_if->name);
	pf_dep_cfg_set_val(RT2860_NVRAM, key, static_netcfg->ipaddr);

	sprintf(key, CT_STATIC_MASK_KEY, dp_if->name);
	pf_dep_cfg_set_val(RT2860_NVRAM, key, static_netcfg->netmask);

	sprintf(key, CT_STATIC_GW_KEY, dp_if->name);
	pf_dep_cfg_set_val(RT2860_NVRAM, key, static_netcfg->defaultgw);

	return (eRET_SUCCESS);
}

e_ret pf_dep_set_if_netcfg_mtu(tdp_if * dp_if, unsigned short mtu)
{
	char key[NVRAM_CFG_KEY_SIZE] = { 0 };
	char val[8] = { 0 };

	sprintf(key, NETCFG_MTU_KEY, dp_if->name);
	sprintf(val, "%d", mtu);
	pf_dep_cfg_set_val(RT2860_NVRAM, key, val);
	return (eRET_SUCCESS);

}

e_ret pf_dep_set_if_netcfg_dns(tdp_if * dp_if, unsigned char manual, tdp_if_dns * dns)
{
	char key[NVRAM_CFG_KEY_SIZE] = { 0 };

	if (manual) {
		sprintf(key, NETCFG_MANUAL_DNS_KEY, dp_if->name);
		pf_dep_cfg_set_val(RT2860_NVRAM, key, "y");
		sprintf(key, NETCFG_DNS1_KEY, dp_if->name);
		pf_dep_cfg_set_val(RT2860_NVRAM, key, dns->dns1);
		sprintf(key, NETCFG_DNS2_KEY, dp_if->name);
		pf_dep_cfg_set_val(RT2860_NVRAM, key, dns->dns2);
	} else {
		sprintf(key, NETCFG_MANUAL_DNS_KEY, dp_if->name);
		pf_dep_cfg_set_val(RT2860_NVRAM, key, "n");
	}

	return (eRET_SUCCESS);

}

e_ret pf_dep_set_if_netcfg_dhdpd(tdp_if * dp_if, tdhcpd_cfg * dhcpd_cfg)
{
	char key[NVRAM_CFG_KEY_SIZE] = { 0 };
	char val[32] = { 0 };

	if (dhcpd_cfg->dhcpd_type == eDP_IF_DHCPD_TYPE_ENABLE) {
		sprintf(key, NETCFG_DHCPD_POOL_START_KEY, dp_if->name);
		pf_dep_cfg_set_val(RT2860_NVRAM, key, dhcpd_cfg->start);

		sprintf(key, NETCFG_DHCPD_POOL_END_KEY, dp_if->name);
		pf_dep_cfg_set_val(RT2860_NVRAM, key, dhcpd_cfg->end);

		sprintf(key, NETCFG_DHCPD_NETMASK_KEY, dp_if->name);
		pf_dep_cfg_set_val(RT2860_NVRAM, key, dhcpd_cfg->netmask);

		sprintf(key, NETCFG_DHCPD_DEFAULT_GW_KEY, dp_if->name);
		pf_dep_cfg_set_val(RT2860_NVRAM, key, dhcpd_cfg->defaultgw);

		sprintf(key, NETCFG_DHCPD_LEASE_KEY, dp_if->name);
		sprintf(val, "%lu", dhcpd_cfg->lease);
		pf_dep_cfg_set_val(RT2860_NVRAM, key, val);

		sprintf(key, NETCFG_DHCPD_DNS1_KEY, dp_if->name);
		pf_dep_cfg_set_val(RT2860_NVRAM, key, dhcpd_cfg->dns.dns1);

		sprintf(key, NETCFG_DHCPD_DNS2_KEY, dp_if->name);
		pf_dep_cfg_set_val(RT2860_NVRAM, key, dhcpd_cfg->dns.dns2);
	}

	sprintf(key, NETCFG_DHCPD_TYPE_KEY, dp_if->name);
	sprintf(val, "%d", dhcpd_cfg->dhcpd_type);
	pf_dep_cfg_set_val(RT2860_NVRAM, key, val);

	return (eRET_SUCCESS);
}

static void mtk_wlan_get_bitrate(unsigned char MODE, unsigned char ShortGI, unsigned char BW,
				 unsigned char MCS, unsigned long *rate)
{

	const static unsigned long RalinkRate_VHT_1NSS[Rate_BW_MAX][Rate_GI_MAX][Rate_MCS] = {
		{
		 {13, 26, 39, 52, 78, 104, 117, 130, 156, 0}, {14, 29, 43, 57, 87, 115, 130, 144, 173, 0}	/*20MHz, 800ns & 400 ns GI, MCS0~9 */
		 },
		{
		 {27, 54, 81, 108, 162, 216, 243, 270, 324, 360}, {30, 60, 90, 120, 180, 240, 270, 300, 360, 400}	/*40MHz, 800ns & 400 ns GI, MCS0~9 */
		 },
		{
		 {59, 117, 176, 234, 351, 468, 527, 585, 702, 780}, {65, 130, 195, 260, 390, 520, 585, 650, 780, 867}	/*80MHz, 800ns & 400 ns GI, MCS0~9 */
		 },
	};
	const static unsigned long RalinkRate_HT_1NSS[Rate_BW_MAX][Rate_GI_MAX][Rate_MCS] = {
		{
		 {13, 26, 39, 52, 78, 104, 117, 130, 0, 0}, {14, 29, 43, 57, 87, 115, 130, 144, 0, 0}	/*20MHz, 800ns & 400 ns GI, MCS0~9 */
		 },
		{
		 {27, 54, 81, 108, 162, 216, 243, 270, 0, 0}, {30, 60, 90, 120, 180, 240, 270, 300, 0, 0}	/*40MHz, 800ns & 400 ns GI, MCS0~9 */
		 },
		{
		 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}	/*80MHz, 800ns & 400 ns GI, MCS0~9 */
		 },
	};
	const static unsigned long RalinkRate_Legacy[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };

#define NewRateGetAntenna(MCS) (((MCS) >> 4) + 1)

	unsigned long MCS_1NSS = MCS;
	unsigned char Antenna = NewRateGetAntenna(MCS);

	*rate = 0;

	sysmgr_dbg("MODE: %x shortGI: %x BW: %x MCS: %x Antenna: %x \n", MODE, ShortGI, BW, MCS, Antenna);

	if ((BW >= Rate_BW_MAX) || (ShortGI >= Rate_GI_MAX)) {
		sysmgr_err("Invalid BW or ShortGI.\n");
		return;
	}

	if (MODE >= MODE_VHT) {
		if (MCS_1NSS > 9) {
			Antenna = (MCS / 10) + 1;
			MCS_1NSS %= 10;
		}
		*rate = RalinkRate_VHT_1NSS[BW][ShortGI][MCS_1NSS];
	} else {
		if ((MODE >= MODE_HTMIX) && (MODE < MODE_VHT)) {
			if (MCS_1NSS > 7) {
				Antenna = (MCS / 8) + 1;
				MCS_1NSS %= 8;
			}
			*rate = RalinkRate_HT_1NSS[BW][ShortGI][MCS_1NSS];
		} else {
			if (MODE == MODE_OFDM) {
				*rate = RalinkRate_Legacy[MCS_1NSS + 4];
			} else {
				*rate = RalinkRate_Legacy[MCS_1NSS];
			}
		}
	}

	*rate *= 500000;
	if (MODE >= MODE_HTMIX) {
		*rate *= Antenna;
	}

	sysmgr_dbg("MODE: %x, shortGI: %x, BW: %x, MCS: %lx, Antenna: %x, Rate: %lu Bits/S\n",
		   MODE, ShortGI, BW, MCS_1NSS, Antenna, *rate);

}

e_ret pf_dep_wlan_set_wsc_get_conf(tdp_if * dp_if, const unsigned char mode)
{
	int rc = -1;
	char iwpriv_arg[128];

	sysmgr_dbg("if[%s], set Wsc Get Conf -> [%d]\n", dp_if->name, mode);

	sprintf(iwpriv_arg, "%s=%d", WLAN_WSC_GET_CONF, mode);
	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);
	if (rc < 0)
		return (eRET_FAILURE);
	else
		return (eRET_SUCCESS);
}

e_ret pf_dep_wlan_set_wsc_mode(tdp_if * dp_if, const unsigned char mode)
{

	int rc = -1;
	char iwpriv_arg[128];

	sysmgr_dbg("if[%s], set Wsc Mode -> [%d]\n", dp_if->name, mode);

	sprintf(iwpriv_arg, "%s=%d", WLAN_WSC_MODE, mode);
	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);

	if (rc < 0)
		return (eRET_FAILURE);
	else
		return (eRET_SUCCESS);
}

e_ret pf_dep_wlan_set_wsc_pin_code(tdp_if * dp_if, unsigned long pin)
{

	int rc = -1;
	char iwpriv_arg[128];

	sysmgr_dbg("if[%s], set Wsc Pin Code -> [%lu]\n", dp_if->name, pin);

	sprintf(iwpriv_arg, "%s=%lu", WLAN_WSC_PIN_CODE, pin);
	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);

	if (rc < 0)
		return (eRET_FAILURE);
	else
		return (eRET_SUCCESS);
}

e_ret pf_dep_wlan_set_wsc_vendor_pin_code(tdp_if * dp_if, unsigned long pin)
{

	int rc = -1;
	char iwpriv_arg[128];

	sysmgr_dbg("if[%s], set Wsc Pin Code -> [%lu]\n", dp_if->name, pin);

	sprintf(iwpriv_arg, "%s=%lu", WLAN_WSC_VENDOR_PIN_CODE, pin);
	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);

	if (rc < 0)
		return (eRET_FAILURE);
	else
		return (eRET_SUCCESS);
}

unsigned char random_byte()
{
	char val;
	int fd;

	fd = open("/dev/urandom", O_RDONLY);
	if (fd < 0) {
		return (0);
	}

	if (read(fd, &val, 1) != 1) {
		val = 0;
		goto out;
	}

out:
	close(fd);

	return (val);

}

int my_checksum(unsigned int pin)
{
	int digit_s;
	unsigned int accum = 0;

	pin *= 10;
	accum += 3 * ((pin / 10000000) % 10);
	accum += 1 * ((pin / 1000000) % 10);
	accum += 3 * ((pin / 100000) % 10);
	accum += 1 * ((pin / 10000) % 10);
	accum += 3 * ((pin / 1000) % 10);
	accum += 1 * ((pin / 100) % 10);
	accum += 3 * ((pin / 10) % 10);

	digit_s = (accum % 10);
	return ((10 - digit_s) % 10);
}				/* ComputeChecksum */

e_ret pf_dep_wlan_set_wsc_gen_pin_code(unsigned int *pin)
{

	unsigned char sleep_val[3];
	unsigned char ran_byte[3];
	unsigned int pin_code;
	unsigned int checksum;

	sleep_val[0] = random_byte();
	usleep(sleep_val[0]);
	ran_byte[0] = random_byte();

	sleep_val[1] = random_byte();
	usleep(sleep_val[1]);
	ran_byte[1] = random_byte();

	sleep_val[2] = random_byte();
	usleep(sleep_val[2]);
	ran_byte[2] = random_byte();

	pin_code = ran_byte[0] * 256 * 256 + ran_byte[1] * 256 + ran_byte[2];

	pin_code = pin_code % 10000000;

	checksum = my_checksum(pin_code);
	pin_code = pin_code * 10 + checksum;

	*pin = pin_code;
	return (eRET_SUCCESS);
}

e_ret pf_dep_wlan_set_wsc_enable(tdp_if * dp_if, const e_bool enable)
{

	char enable_val[4];

	sysmgr_dbg("if[%s], set Wsc Enable -> [%d]\n", dp_if->name, enable);
	if (enable) {
		sprintf(enable_val, "1");
	} else {
		sprintf(enable_val, "0");
	}

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_WSC_ENABLE, enable_val);
	} else {
		pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_WSC_ENABLE, enable_val);
	}

	return (eRET_SUCCESS);
}

e_ret pf_dep_wlan_set_wsc_configed(tdp_if * dp_if, const e_bool configed)
{

	char enable_val[4];

	sysmgr_dbg("if[%s], set Wsc Enable -> [%d]\n", dp_if->name, configed);
	if (configed) {
		sprintf(enable_val, "1");
	} else {
		sprintf(enable_val, "0");
	}

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
		pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_WSC_CONFIGED, enable_val);
	} else {
		pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_WSC_CONFIGED, enable_val);
	}

	return (eRET_SUCCESS);
}

e_ret pf_dep_wlan_set_wsc_v2_support(tdp_if * dp_if, const unsigned char enable)
{
	int rc = -1;
	char iwpriv_arg[128];

	sysmgr_dbg("if[%s], set WscV2 Support -> [%d]\n", dp_if->name, enable);

	sprintf(iwpriv_arg, "%s=%d", WLAN_WSC_V2_SUPPORT, enable);
	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);

	if (rc < 0)
		return (eRET_FAILURE);
	else
		return (eRET_SUCCESS);
}

e_ret pf_dep_wlan_set_wsc_conf_mode(tdp_if * dp_if, const unsigned char mode)
{
	int rc = -1;
	char iwpriv_arg[128];

	sysmgr_dbg("if[%s], set Wsc Conf Mode -> [%d]\n", dp_if->name, mode);

	sprintf(iwpriv_arg, "%s=%d", WLAN_WSC_CONF_MODE, mode);
	rc = do_iwpriv(dp_if->name, "set", iwpriv_arg);

	if (rc < 0)
		return (eRET_FAILURE);
	else
		return (eRET_SUCCESS);
}

e_ret pf_dep_wlan_set_wsc_conf_status(tdp_if * dp_if, const unsigned char status, e_bool save)
{
	int rc = -1;
	char iwpriv_arg[128];
	char cfg_status_val[4];
	char *if_name;

	sysmgr_dbg("if[%s], set Wsc Conf Status -> [%d]\n", dp_if->name, status);

	if (dp_if->type == eDP_IF_TYPE_WLAN24G_CLI) {
		if_name = "ra0";
	} else if (dp_if->type == eDP_IF_TYPE_WLAN5G_CLI) {
		if_name = "rai0";
	} else {
		if_name = dp_if->name;
	}

	if (save) {
		sprintf(iwpriv_arg, "%s=%d", WLAN_WSC_CONF_STATUS, status);
		rc = do_iwpriv(if_name, "set", iwpriv_arg);

		sprintf(cfg_status_val, "%d", status);
		if (dp_if->type == eDP_IF_TYPE_WLAN24G_AP) {
			pf_dep_cfg_set_val(RT2860_NVRAM, WLAN_WSC_CONF_STATUS, cfg_status_val);
		} else if (dp_if->type == eDP_IF_TYPE_WLAN5G_AP) {
			pf_dep_cfg_set_val(RTDEV_NVRAM, WLAN_WSC_CONF_STATUS, cfg_status_val);
		}
	}

	if (rc < 0)
		return (eRET_FAILURE);
	else
		return (eRET_SUCCESS);
}

e_ret pf_dep_wlan_get_wsc_profile(tdp_if * dp_if, twlan_wsc_profile * prof)
{

	typedef struct __attribute__ ((packed)) {
		unsigned short WscConfigured;	// 1 un-configured; 2 configured
		unsigned char WscSsid[32 + 1];
		unsigned char WscSsidLen;
		unsigned short WscAuthMode;	// mandatory, 0x01: open, 0x02: wpa-psk, 0x04: shared, 0x08:wpa, 0x10: wpa2, 0x
		unsigned short WscEncrypType;	// 0x01: none, 0x02: wep, 0x04: tkip, 0x08: aes
		unsigned char DefaultKeyIdx;
		unsigned char WscWPAKey[64 + 1];
		unsigned char WscWPAKeyLen;
	} WSC_CONFIGURED_VALUE_PACKED;

	int rc;
	int sockfd;
	e_ret ret;
	struct iwreq iwrq;
	char *input;
	WSC_CONFIGURED_VALUE_PACKED data;

	sysmgr_dbg("if[%s], get Wsc Profile\n", dp_if->name);

	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if (sockfd < 0) {
		sysmgr_err("socket() failed, err: %d,[%s]\n", errno, strerror(errno));
		return (eRET_FAILURE);
	}

	input = (void *)&data;

	strcpy(iwrq.ifr_name, dp_if->name);
	strcpy(input, "get_wsc_profile");
	iwrq.u.data.length = sizeof(data);
	iwrq.u.data.pointer = &data;
	iwrq.u.data.flags = 0;
	rc = ioctl(sockfd, RTPRIV_IOCTL_WSC_PROFILE, &iwrq);
	sysmgr_dbg("ioctl(%s, RTPRIV_IOCTL_WSC_PROFILE), rc: %d\n", dp_if->name, rc);
	if (rc < 0) {
		sysmgr_err("ioctl(%s, RTPRIV_IOCTL_WSC_PROFILE) failed, err: %d,[%s]\n", dp_if->name, errno,
			   strerror(errno));
		ret = eRET_FAILURE;
		goto out;
	}

	prof->wsc_configured = data.WscConfigured;
	strcpy(prof->wsc_ssid, data.WscSsid);
	prof->wsc_auth_mode = data.WscAuthMode;
	prof->wsc_encryp_type = data.WscEncrypType;
	prof->wsc_default_key_idx = data.DefaultKeyIdx;
	strcpy(prof->wsc_wpapsk, data.WscWPAKey);

	ret = eRET_SUCCESS;

out:
	close(sockfd);
	return (ret);
}

e_ret pf_dep_wlan_get_wsc_status(tdp_if * dp_if, int *status)
{

	int rc;
	int sockfd;
	e_ret ret;
	struct iwreq iwrq;
	int data;

	sysmgr_dbg("if[%s], get Wsc Status\n", dp_if->name);

	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if (sockfd < 0) {
		sysmgr_err("socket() failed, err: %d,[%s]\n", errno, strerror(errno));
		return (eRET_FAILURE);
	}

	strcpy(iwrq.ifr_name, dp_if->name);
	iwrq.u.data.length = sizeof(data);
	iwrq.u.data.pointer = &data;
	iwrq.u.data.flags = RT_OID_WSC_QUERY_STATUS;
	data = 0;
	rc = ioctl(sockfd, RT_PRIV_IOCTL, &iwrq);
	sysmgr_dbg("ioctl(%s, RT_PRIV_IOCTL), rc: %d\n", dp_if->name, rc);
	if (rc < 0) {
		sysmgr_err("ioctl(%s, RT_PRIV_IOCTL) failed, err: %d,[%s]\n", dp_if->name, errno, strerror(errno));
		ret = eRET_FAILURE;
		goto out;
	}

	ret = eRET_SUCCESS;

	*status = data;

out:
	close(sockfd);
	return (ret);
}

const char *pd_def_get_wsc_status_str(int status)
{
	switch (status) {
	case 0:
		return "Not used";
	case 1:
		return "Idle";
	case 2:
		return "WSC Fail(Ignore this if Intel/Marvell registrar used)";
	case 3:
		return "Start WSC Process";
	case 4:
		return "Received EAPOL-Start";
	case 5:
		return "Sending EAP-Req(ID)";
	case 6:
		return "Receive EAP-Rsp(ID)";
	case 7:
		return "Receive EAP-Req with wrong WSC SMI Vendor Id";
	case 8:
		return "Receive EAPReq with wrong WSC Vendor Type";
	case 9:
		return "Sending EAP-Req(WSC_START)";
	case 10:
		return "Send M1";
	case 11:
		return "Received M1";
	case 12:
		return "Send M2";
	case 13:
		return "Received M2";
	case 14:
		return "Received M2D";
	case 15:
		return "Send M3";
	case 16:
		return "Received M3";
	case 17:
		return "Send M4";
	case 18:
		return "Received M4";
	case 19:
		return "Send M5";
	case 20:
		return "Received M5";
	case 21:
		return "Send M6";
	case 22:
		return "Received M6";
	case 23:
		return "Send M7";
	case 24:
		return "Received M7";
	case 25:
		return "Send M8";
	case 26:
		return "Received M8";
	case 27:
		return "Processing EAP Response (ACK)";
	case 28:
		return "Processing EAP Request (Done)";
	case 29:
		return "Processing EAP Response (Done)";
	case 30:
		return "Sending EAP-Fail";
	case 31:
		return "WSC_ERROR_HASH_FAIL";
	case 32:
		return "WSC_ERROR_HMAC_FAIL";
	case 33:
		return "WSC_ERROR_DEV_PWD_AUTH_FAIL";
	case 34:
		return "Configured";
	case 35:
		return "SCAN AP";
	case 36:
		return "EAPOL START SENT";
	case 37:
		return "WSC_EAP_RSP_DONE_SENT";
	case 38:
		return "WAIT PINCODE";
	case 39:
		return "WSC_START_ASSOC";
	case 0x101:
		return "PBC:TOO MANY AP";
	case 0x102:
		return "PBC:NO AP";
	case 0x103:
		return "EAP_FAIL_RECEIVED";
	case 0x104:
		return "EAP_NONCE_MISMATCH";
	case 0x105:
		return "EAP_INVALID_DATA";
	case 0x106:
		return "PASSWORD_MISMATCH";
	case 0x107:
		return "EAP_REQ_WRONG_SMI";
	case 0x108:
		return "EAP_REQ_WRONG_VENDOR_TYPE";
	case 0x109:
		return "PBC_SESSION_OVERLAP";
	default:
		return "Unknown";
	}
}

#if 0
void check_esw_port_reg()
{
	extern int raesw_init(void);
	extern void raesw_finish(int fd);
	extern int raesw_reg_write(int fd, int offset, int value);
	extern int raesw_reg_read(int fd, int offset, int *value);

	int ret_val;
	int esw_fd;
	int i = 100;

	esw_fd = raesw_init();
	if (esw_fd < 0) {
		return;
	}

	while (i-- > 0) {
		raesw_reg_read(esw_fd, 0x2400, &ret_val);
		sysmgr_err("0x2400: 0x%08X\n", ret_val);

		raesw_reg_read(esw_fd, 0x2404, &ret_val);
		sysmgr_err("0x2404: 0x%08X\n", ret_val);

		raesw_reg_read(esw_fd, 0x2408, &ret_val);
		sysmgr_err("0x2408: 0x%08X\n", ret_val);

		raesw_reg_read(esw_fd, 0x240C, &ret_val);
		sysmgr_err("0x240C: 0x%08X\n", ret_val);

		raesw_reg_read(esw_fd, 0x3400, &ret_val);
		sysmgr_err("0x3400: 0x%08X\n", ret_val);

		raesw_reg_read(esw_fd, 0x3404, &ret_val);
		sysmgr_err("0x3404: 0x%08X\n", ret_val);

		raesw_reg_read(esw_fd, 0x3408, &ret_val);
		sysmgr_err("0x3408: 0x%08X\n", ret_val);

		raesw_reg_read(esw_fd, 0x3410, &ret_val);
		sysmgr_err("0x3410: 0x%08X\n", ret_val);

		raesw_reg_read(esw_fd, 0x3414, &ret_val);
		sysmgr_err("0x3414: 0x%08X\n", ret_val);

		raesw_reg_read(esw_fd, 0x3FE0, &ret_val);
		sysmgr_err("0x3FE0: 0x%08X\n", ret_val);

		raesw_reg_read(esw_fd, 0x3FE4, &ret_val);
		sysmgr_err("0x3FE4: 0x%08X\n", ret_val);

		raesw_reg_read(esw_fd, 0x3FE8, &ret_val);
		sysmgr_err("0x3FE8: 0x%08X\n", ret_val);
		sleep(1);
	}

	raesw_finish(esw_fd);

}
#endif
